深入理解js中的apply、call、bind
概述
js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向。
apply()
apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。
var student = {
name : 'xiaoming'
}
function getName(firstName , lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName)
}
getName.apply(student , ['MQ' , 'jj']); //MQ xiaoming jj
call()
call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。
var student = {
name : 'xiaoming'
}
function getName(firstName , lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName)
}
getName.call(student , 'MQ' , 'jj'); //MQ xiaoming jj
apply(),call()常用方法
1.数组合并
var arr_1 = [1,2,3];
var arr_2 = [4,5,6];
[].push.apply(arr_1,arr_2);
console.log(arr_1) //[1,2,3,4,5,6]
2.获取数组中的最大值和最小值
var num_arr = [3,5,8,1,9];
var max_num = Math.max.apply(Math , num_arr);
var min_num = Math.min.call(Math , 3 , 5 , 8 , 1 , 9)
console.log(max_num) //9
console.log(min_num) //1
3.类(伪)数组使用数组方法
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
bind()方法
bind()方法与call(),apply()类试,也可改变函数体内的this指向。
bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
var foo = {
bar : 1,
eventBind: function(){
var _this = this;
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(_this.bar); //1
});
}
}
使用bind解决保存this的问题
var foo = {
bar : 1,
eventBind: function(){
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(this.bar); //1
}.bind(this));
}
}
bind参数的使用:
var student = {
name : 'xiaoming'
}
function getName(firstName , lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName)
}
var getBindName = getName.bind(student,'lihui');
getName('Mrs','jj'); //Mrs jj
getBindName(); //lihui xiaoming undefined
getBindName('jj'); //lihui xiaoming jj
getBindName('Mrs','jj'); //lihui xiaoming Mrs
getName.call(student,'lihui') //lihui xiaoming undefined
call 是把第二个及以后的参数作为 getName方法的实参传进去,而 getBindName方法的实参实则是在 bind 中参数的基础上再往后排。
apply、call、bind三者之间的比较
var student = {
age : 18
}
var studentInfo = {
getAge () {
return this.age
}
}
console.log(studentInfo.getAge.bind(student)()); //18
console.log(studentInfo.getAge.call(student)); //18
console.log(studentInfo.getAge.apply(student)); //18
apply/call在改变函数上下文环境之后, 会立即执行函数。而bind()不会立即执行,而是返回一个改变了上下文 this 后的函数。
总结
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向
- apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文
- apply 、 call 、bind 三者都可以利用后续参数传参,只是方式不同
- apply , call改变函数上下文之后会立即调用,而bind会返回一个改变了this的函数,以便以后调用
参考资料
1.【优雅代码】深入浅出 妙用javascript的call , apply , bind
深入理解js中的apply、call、bind的更多相关文章
- JS中的apply,call,bind深入理解
在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...
- js 中call,apply,bind的区别
call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...
- 图文结合深入理解 JS 中的 this 值
图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...
- 如何理解js中的this和实际应用中需要避开哪些坑
this是什么 this就是函数内部的关键字 看下面例子理解js中的this // 例子1 function fnOne () { console.log(this) } 'use strict' f ...
- 深入理解Js中的this
深入理解Js中的this JavaScript作用域为静态作用域static scope,但是在Js中的this却是一个例外,this的指向问题就类似于动态作用域,其并不关心函数和作用域是如何声明以及 ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 深入理解JS中的对象(二):new 的工作原理
目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...
- 深入理解JS中的对象(三):class 的工作原理
目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...
- 如何更好的理解js中的this,分享2段有意思的代码
关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...
随机推荐
- 将 C# 枚举反序列化为 JSON 字符串 实践
一.定义枚举 public enum SiteTypeEnum { 中转部 = 1, 网点 = 2 } 还有 BooleanEnum 和 OptTypeEnum 这两个枚举,这里暂且省略了它们的定义. ...
- PE格式第六讲,导出表
PE格式第六讲,导出表 请注意,下方字数比较多,其实结构挺简单,但是你如果把博客内容弄明白了,对你受益匪浅,千万不要看到字数多就懵了,其实字数多代表它重要.特别是第五步, 各种表中之间的关系. 作者: ...
- Python基础2 编码和逻辑运算符
编码: AscII码 :标准ASCII码是采用7位二进制码来编码的,当用1个字节(8位二进制码)来表示ASCII码时,就在最高位添加1个0. 一个英文字母占一个字节 8位(bit)==一个字节(byt ...
- XamlReader动态使用xaml
xamlload先在xaml做出一个grid,命名xgrid <Page x:Class="xamlload.MainPage" xmlns="http://sch ...
- JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 3
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7718741.html ------------------------------------ ...
- Chrome等浏览器下出现net::ERR_BLOCKED_BY_CLIENT的解决办法
当我们在做开发时,调试页面图片会出现部分图片无法正常显示,并且确认图片的地址正确: 按F12 Debug查看报错原因,提示net::ERR_BLOCKED_BY_CLIENT错误,但当我们点击图片地址 ...
- eclipse创建一个文件夹
如何给eclipse创建一个文件夹,便于项目的管理:有时我们的eclipse中会有很多项目的,有的是公司的如Project1,Project2,Project3....还有的呢, 也可能是自己平时做的 ...
- Linux驱动模型解析bus之platform bus
这是内核启动之后要调用的驱动模型的开始代码: drivers/base/init.c/** * driver_init - initialize driver model. * * Call the ...
- Disharmony Trees
/* 写完这篇博客有很多感慨,过去一段时间都是看完题解刷题,刷题,看会题解,没有了大一那个时候什么都不会的时候刷题的感觉,这个题做了一天半,从开始到结束都是从头开始自己构思的很有感觉,找回到当初的感觉 ...
- IdentityServer4实现Token认证登录以及权限控制
相关知识点 不再对IdentityServer4做相关介绍,博客园上已经有人出了相关的系列文章,不了解的可以看一下: 蟋蟀大神的:小菜学习编程-IdentityServer4 晓晨Master:Ide ...