JavaScript普通函数中的this指向判断,箭头函数的this有什么不同?
1、普通函数
先说说普通函数中的this,各式各样的情况下判断this的指向,可以说是非常刁钻了。判断的时候,只要记住【this 永远指向调用它的对象,new的时候,指向new出来的对象。】这句话就够了。
看几个例子:
//例1 var obj = { name: 'latency', sayname: function(){ console.log('name:',this.name); } } obj.sayname() //name: latency
例1这个例子很好理解,sayname() 方法是 obj 调用的,所以其中的this指向obj。
//例2 var name = 'cheng'; var obj = { name: 'latency', sayname: function(){ return function(){ console.log('name:',this.name); } } } obj.sayname()() //name: cheng
在例2中,打印出来对的this.name不是obj的name,而是window对象的name属性。这是因为sayname()函数中有个闭包,闭包中的this指向调用这个闭包的对象,也就是window对象,写成下面这样可能更好理解:
var fun = obj.sayname(); fun() //name: cheng fun()方法是window对象调用的,其this指向window对象
接下来看一个复杂一点的例子:
//例3 var fun = function (a){ this.a = a; return function(b){ console.log('a+b:', this.a + b); } }((function(a,b){return a})(1,2)) fun(3) //a+b: 4
在例3中,首先要明确fun是什么,仔细看代码第7行,我们发现fun是一个立即执行的函数,它的参数也是一个立即执行的函数。
(function(a,b){return a})(1,2) 执行的结果是1,所以fun实际上是下面这样var fun = (function(a){......})(1)
在fun定义的时候,就已经开始执行了,执行结果如下:
var fun = function (a){ //a = 1 this.a = a; //this.a = 1 return function(b){ console.log('a+b:', this.a + b); } }(1)
当执行到fun(3)的时候,fun中的闭包函数开始执行,传入参数b=3,由于此时调用闭包函数的是fun,所以闭包中的this指向fun,从而得出 this.a + b 的值为4。
以上是普通函数中的this,下面来看箭头函数中的this。
2、箭头函数
对于箭头函数的this,也只需要记住一句话【箭头函数没有自己的 this,当在内部使用了 this时,它会指向最近一层作用域内的 this】
上例子,可以把例2改成箭头函数,让它的表现符合我们的预期
//例4 var obj = { name: 'latency', sayname: function(){ return () => { console.log('name:', this.name); } } } obj.sayname()() //name: latency
在例4中,return的是一个箭头函数,没有把this绑定到自己的内部,使用this时,指向的是上一层的obj。
//例5 var name = 'cheng'; function delay(){ settimeout(function(){ console.log('name:', this.name); }, 100) } function arrowdelay(){ settimeout(() => { console.log('name:', this.name); }, 100) } delay.call({name: 'latency'}) //name: cheng arrowdelay.call({name: 'latency'}) //name: latency
这个例子就可以很清楚的看出箭头函数和普通函数中this的区别。
根据上面两个例子,我们可以总结出,在函数中需要使用闭包的时候,用箭头函数就很方便了,不需要像以前一样使用hack,类似 var context = this;
接下来把例1改成箭头函数来实现,看看结果:
//例6 var name = 'cheng'; var obj = { name: 'latency', sayname: () => { console.log('name:', this.name) } } obj.sayname() //name: cheng
由于sayname()整个函数就是一个箭头函数,没有自己的this,所以this指向的最近一层作用域内的this,也就是window对象。这种情况下,就不适合用箭头函数来实现了。
再看一个例子
//例7 var obj = { name: 'latency', sayname: function(){ return () => { return () => { return () => { console.log("name:", this.name); }; }; }; } } obj.sayname()()()() //name: latency
这个例子可以更好地帮助我们理解【箭头函数没有自己的 this,当在内部使用了 this时,它会指向最近一层作用域内的 this】这句话。这个例子定义了三个箭头函数,它们都没有绑定this到自己的内部,或者说没有改变this的指向,所以this始终指向obj。
推荐阅读
-
JavaScript中的普通函数和箭头函数的区别和用法详解
-
JavaScript普通函数中的this指向判断,箭头函数的this有什么不同?
-
区别ES3ES5和ES6this的指向问题。区分普通函数和箭头函数中this的指向问题
-
JavaScript中的普通函数和箭头函数的区别和用法详解
-
JavaScript普通函数中的this指向判断,箭头函数的this有什么不同?
-
JavaScript中的普通函数和箭头函数的区别和用法详解
-
区别ES3ES5和ES6this的指向问题。区分普通函数和箭头函数中this的指向问题
-
JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?
-
在JavaScript函数中this指向的是什么
-
js中的箭头函数和普通函数有什么区别