call的初步理解
首先说下call的本质是一个函数
模仿
Function.prototype.call = function(context){
// this表示某函数,函数里面的this先被替换成context,然后再执行
this.bind(context)(); }
然后理解这个
Function.prototype.call.call(context);
// 相当于
this.bind(context)();
// this指Function.prototype.call,于是相当于
Function.prototype.call.bind(context)();
// 因为Function.prototype.call这个函数里面的this变成了context
context.bind(context)();
然后再理解理解这个
Function.prototype.call.call.call(context); // 相当于 this.bind(context)();// this指Function.prototype.call.call,因为call本身就是函数,而任何函数的call属性相当于Function.prototype.call,也就是Function.prototype.call.call = Function.prototype.call,然后this实际还是指Function.prototype.call,重复上面的说
Function.prototype.call.bind(context)();
// 因为Function.prototype.call这个函数里面的this变成了context
context.bind(context)();
然后,看一个demo:
function fn1(){ console.log(1) } function fn2(){ console.log(2) } // Function.prototype.call(fn2);this指当前的实例fn1,fn1里面的this是fn2 fn1.call(fn2); // Function.prototype.call.call(fn2);this指Function.prototype.call,Function.prototype.call里面的this是fn2 fn1.call.call(fn2); // 相当于 fn2(); //其实只要超过一个call,都是fn2()
所以call函数执行,主要看call函数里面的this指哪个函数,这个函数自己里面的this换成指定context,然后执行
说另外一个好玩的,call可以改变函数的this的值,但在非严格模式下,fn.call(),fn.call(null),fn.call(undefined),这些写法将this的值指向window,严格模式下,指啥是啥
var obj = { fn:function(){ console.log(this) } } var n = { name:"hua" } obj.fn.call(null); // window obj.fn(); // obj