ES5和ES6箭头函数this简析
箭头函数的作用:
- 箭头函数让函数的书写变得很简洁,可读性更好
- 解决了匿名函数this指向的问题(匿名函数的执行环境具有全局性),包括setTimeout和setInterval中使用this所造成的问题。
ES5
全局环境下,this 始终指向全局对象(window), 无论是否严格模式;
console.log(this.document=== document); // true
console.log(this === window); // true
this.a = 'aaa';
console.log(window.name); // aaa
函数直接调用
普通函数内部的this分两种情况,严格模式和非严格模式。
非严格模式下,this 默认指向全局对象window
function f2(){
return this;
}
console.log(f2()); //window
严格模式下, this为undefined
function f2(){
"use strict"; // 严格模式
return this;
}
console.log(f2()); //undefined
ES5中 this 的指向
var x = function(){
this.a = 'a';
this.b = 'b';
this.c = {
a:'1',
b:function(){return this.a}
}
};
console.log(new factory().c.b());
//结果:1
调用函数返回值为1,this 的指向是该函数被调用的对象,也就是说函数被调用的时候,this 指向的是对象调用的这个函数。
ES6
箭头函数的this指向:箭头函数在定义时执行器上下文的this的指向(不具有块级作用域),即会取当前的函数的作用域链上的this,忽略块级作用域中的this,简单概括:
- es6箭头函数没有自己的this
- es6箭头函数里的this是外层代码(定义时,非执行时)this的引用
var x= function(){
this.a = 'a';
this.b = 'b';
this.c = {
a:'1',
b:() => {return this.a}
}
};
console.log(new factory().c.b()); // a
箭头函数函数体中 this 的指向是定义时 this 的指向。在定义 b 函数时,b当中的 this 指向的是 这个x函数体中的 this ,这个x函数体中的 this 指向的是这个构造函数的实例,这个实例当中的 a 就等于 ‘a’;虽然是调用的b对象,但这个b对象指向的是这个实例。
ES5和ES6对比
ES5中
var a=1;
var obj={
a:2,
say:function(){
console.log(this.a)
}
}
obj.say(); //结果:2
ES6中
var a=1;
var obj={
a:2,
say:()=>{
console.log(this.a);
}
}
obj.say();//1
对比分析:
由上面的代码可以看出ES5中this指向的是obj这个对象,ES6箭头函数中的this是定义时绑定的,就是this是继承自父执行上下文
中的this,比如这里的箭头函数中的this.a,箭头函数本身与say平级以key:value的形式,也就是箭头函数本身所在的对象为obj,而obj的父执行上下文就是window
,因此这里的this.a
实际上表示的是window.a
,因此输出的是1
。
var a=1;
function x(){
this.a=2;
let b=function(){
console.log(this.a);
};
b();
}
var y=new x();//结果:1
var a1=1
function x1(){
this.a1=2;
let b1=function(){
console.log(this.a1);
};
b1();
}
x1();//结果:2
var a2=1;
function x2(){
this.a2=2;
let b2=()=>{console.log(this.a2)}
b2();
}
var y2=new x2();//结果:2
对比分析:
ES6中定义的时候绑定this的具体含义,应该继承的是父执行上下文里面的this
简单对象(非函数)不执行上下文
箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。