call 和 apply
理解call和apply,从三个方面入手:
1、为什么要用call和apply?
比如有两个对象,A对象有一个酷炫的方法F,B对象没有,就很羡慕,B也想用,然后B对象就开挂,通过逼迫A对象使用F方法时再用call方法,效果就成了B对象在用F方法
function Cat(){}
Cat.prototype = {
food:"fish",
say: function () {
alert("i love " + this.food)
}
};
var whiteCat = new Cat();
whiteCat.say(); //i love fish
var blackDog = {
food:"bone"
};
whiteCat.say.call(blackDog); // i love bone
为什么要用call和apply,就是因为一个对象很懒,想用另一个对象的方法,自己又懒得定义,所以通过call、apply曲线完成。
2、抽象点来说:
call 和 apply 都是为了改变某个函数运行时的context即上下文而存在的,换句话说,就是为了改变函数体内部this的指向。因为javascript函数存在【定义时上下文】和【运行时上下文】以及【上下文是可以改变的】这样的概念。
3、不同之处:
call 接受连续参数,apply 接受数组参数。
function add(j,k){ return j + k; } function sub(j,k){ return j - k; } add.call(sub,5,3); //8 add.apply(sub,[5,3]); //8
4、实现继承
通过call 和 apply 我们可以实现对象继承
var Parent = function () { this.name = 'lihong'; this.age = 29; }; var child = {}; Parent.call(child); console.log(child); //Object{name:‘lihong’,age:29}
bind
bind 功能和call apply 差不多,区别在于bind返回的是一个改变this指向的新函数,这个函数不是立即执行函数(call apply两个立即执行!),跟之前的函数不是一个内存地址,所以我要重复调用这个新函数的话,只有把它保存到一个变量中。
另外我们需要注意,bind函数中的首个参数,会自动成为返回新函数中参数的默认值,so,正式调用时,我们只需给出除首个参数外的其他参数即可。
1 function foo(x,y){ 2 console.log(x+y); 3 } 4 var foo1 = foo.bind(null,1,1); 5 foo1(1);
1 var me = {say:'im a gay'}; 2 var func = function () { 3 return this.say; 4 }; 5 var bind = func.bind(me); 6 var call = func.call(me); 7 var apply = func.apply(me); 8 console.log(bind,bind(),call,apply);
总结:1、 call apply bind 三者都是用来改变函数的this对象指向的;
2、 call apply bind 三者第一个参数都是this要指向的对象;
3、 bind 返回新函数,call apply则立即调用;