call、apply、bind异同点及原理
2017-07-20 本文已影响97人
sdcV
1. 相同点:动态地改变传入函数的this。
2. 不同点
- call和apply传入的参数形式有区别,如:
var func = function(a, b, c){
console.log([a, b, c]);
}
func.apply(null, [1,2,3]); //[1, 2, 3]
func.call(null,1,2,3); //[1,2,3]
原理:当调用一个函数时,JavaScript的解释器并不会计较形参和实参的数量、类型以及顺序,JavaScript的参数内部就是用一个数组表示的。
- 从这点来看,apply比call使用效率更高。我们不必要关心具体有多少参数被传入函数,只要apply推过去就是了。
- call时包装在apply上面的语法糖,我们要明确直到函数接受多少个参数,而且一目了然表达形参和实参的对应关系,可以用call传参。
-
bind和call、apply的区别在于bind返回的是<b>待执行的函数。</b>
模拟一个bind的实现
Function.prototype.bind = function(context){
var self = this;
return function(){
return self.apply(context, arguments);
}
};var obj = {name: 'sdc'}; var func = function(){ console.log(this.name); }.bind(obj); func(); // sdc
3. 用途:
- 改变this指向
- 借用其它对象的方法
-
借用构造函数
var A = function (name){
this.name = name;
};
var B = function(){
A.apply(this, arguments);
};
B.prototype.getName = function(){
return this.name;
};
var b = new B('sdc');
console.log(b.getName()); // sdc -
类数组借用数组方法
(function(){ //类数组添加一个新元素
Array.prototype.push.call(arguments, 3);
console.log(arguments);
})(1,2)
还有一些slice啥的....比如类数组转成数组Array.prototype.slice.call(arrayLike)
-