关于apply、call和bind的总结
基础知识不是你看了一遍书或者两篇文章就能掌握的。
之前看书看文章时,感觉自己看懂了就掌握了。呵呵!too young!too naive!
高程上面关于apply和call的知识点:
apply和call,这两个方法的用途都是在特定作用域中调用函数,实际上等于设置函数体内this对象的值(this
指当前对象,也就是正在调用这个函数的对象。)。
apply方法
apply方法接收两个参数:一个是在其中运行函数的作用域(this),另一个是参数数组。其中,第二个参数(可选)可以是Array的实例,也可以是arguments对象。
用apply改变this:
var jack = { name:'jack', age:28, sayName:function() { console.log(this.name); } }; var juli = { name:'juli', age:25 }; jack.sayName();//jack jack.sayName.apply(juli);//juli
用apply改变this并传入第二个参数
var ryo = { name:'隆', learn:function(para) { this.shill = para; } }; var ken = { name:'肯' } //通过ryo的learn方法让ken学会波动拳 ryo.learn.apply(ken,['波动拳']);
call方法
call方法与apply方法的作用相同,他们的区别仅在于接收参数的方式不同。
对于call方法,第一个参数与apply方法的第一个参数意义相同。不同的是,在使用call方法时,传递给函数的参数必须逐个列举出来。
把上面的两个例子用call改写,结果完全一样。注意两者传入函数的参数的方式不同。
bind方法
bind方法会创建一个调用bind方法的函数的实例(返回一个绑定函数),该函数实例(绑定函数)的this为传入bind方法的第一个参数。当使用new
操作符调用该函数实例(绑定函数)时,第一个参数无效。
通过bind方法还可以预设返回的函数实例(绑定函数)的参数,方法是给bind方法传入除第一个参数以外的参数。
用bind创建一个原函数的实例:
var name = 'window对象'; function originalFun(para1,para2) { console.log(arguments); console.log(para1 + para2); console.log(this.name); } var funOne = originalFun.bind(); funOne(3,4);
调用funOne函数的输出结果:
创建funOne函数时,没有向bind方法中传入参数,funOne的this被设为window对象。
不过在严格模式下,不传入参数,返回的函数实例的this不会被设为window,以上代码运行时会报错 'Cannot read property 'name' of undefined'。
用bind创建一个原函数的实例并绑定一个this:
var name = 'window对象'; var person = { name:'Gilbert', age:15 }; function originalFun(para1,para2) { console.log(arguments); console.log(para1 + para2); console.log(this.name); } var funTwo = originalFun.bind(person); funTwo(5,6);
调用funTwo函数的输出结果:
用bind创建一个原函数的实例并绑定一个this和预设第一个参数:
var name = 'window对象'; var person = { name:'Gilbert', age:15 }; function originalFun(para1,para2) { console.log(arguments); console.log(para1 + para2); console.log(this.name); } var funThree = originalFun.bind(person,10); funThree(40);
调用funThree函数的输出结果:
用new操作符调用绑定函数时,会忽视传入bind方法的第一个参数。
下面的例子根据MDN的例子改编而来:
var math = { name:'jojo' } function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function() { console.log(this); console.log(this.x + ',' + this.y); }; var CopyPoint = Point.bind(math,0); var aPoint = new CopyPoint(10); aPoint.toString();//输出:{x:0, y:10} 0,10
承接上面的代码,不用new操作符调用绑定函数:
//不用new操作符调用绑定函数 CopyPoint(20); console.log(math);//输出:{name:'jojo', x:0, y:20}
结束语
以上内容只是总结了apply、call、bind的最基础的知识,要想在项目中熟练地使用这三个方法还要有一定的经验积累。
(完)
相关文章:
1.【优雅代码】深入浅出 妙用Javascript中apply、call、bind
参考文章: