三者共同点都是为了解决this的指向问题。
call,apply:
这两个函数都是在特定的作用域中调用函数,能改变函数的作用域,实际上是改变函数体内 this 的值 。同时改变了作用域。
call(thisObj,Object):all 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象.如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply(thisObj,[argArray]):如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
call和apply主要差别在第二个参数,apply传入的是一个数组,而call是将参数是通过“ , ”分隔分别传入。
call 和 apply 最大的好处:方便我们解耦,对象不需要和方法有任何的耦合性,能使我们写出更好的面相对象程序。
**bind:**返回值是一个改变了this指向的函数,且不会立即执行。而call和apply会立即执行。
//对是否支持bind进行判断,若不支持,则创建bind函数
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context,[].concat.call(args, [].slice.call(arguments)));
}
}
}
//代码出自:https://github.com/lin-xin/blog/issues/7
//手写bind函数,对参数的要求进行了一点修改。
Function.prototype.newBind = function(tar){
//定义调用的函数this
var self = this;
// var first = [].shift.call(arguments);
// var args = [].slice.call(arguments);
var f = function(){
var _args = [].slice.call(arguments);
return self.call(tar,_args);
}
return f;
}
var show = function(){
console.log(this);
}
var a = {
age: 23,
name:"czl"
}
var newShow = show.newBind(a,1,2);
newShow(1,2);