ES6箭头函数中this的理解
1.首先看一下普通函数中的this
普通函数中的this就是指向该执行函数的最近调用者对象
1.
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
这里很明显调用者对象是window,上面a() =》window.a()
2.
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
这里也很明显调用者对象是 o,故this为o
3.
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
window.o.fn();
从这例子就能很好的体现‘最近’调用者的概念,实际上例子2和例子3是相同的,
但被调用函数fn()它的最近调用者是对象o,所以this就指向o
4.
下面我们来对比以下的两个函数中的this来巩固上面的结论
(1)
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
(2)
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
明显对比可知,例子(2)较例子(1)fn( )的最近调用者是不存在属性a的,
故例子(2)中的this的属性a理所应当为undefined
- 综上我们可以得出这样的说法:
- (1).如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象
- (2).如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
上面的说法相对是正确的,但之所以说相对,是因为存在一种较为特殊的情况
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j(); // =》window.j()
这里有些同学可能就会有疑惑了,怎么最近调用者对象不是b吗怎么是window,
对此我们不妨这样理解,执行函数是j(),而fn()只是j()执行函数下的一个方法,
因此执行函数j()的最近调用者对象是window,没有问题,关键是不要先入为主的把执行函数拨开来去找最近调用者对象
5.例外:构造函数中的this
function Fn(){
this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子
构造函数中的this就直接指向它实例化出的对象
2.ES6箭头函数中的this
-
(1)首先我们回顾一下,箭头函数的形体变化:
- 1.如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
- 2.如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回
- 3.由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
- 4.如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。
let fn = () => void doesNotReturn();
-
(2)箭头函数中的this
- 同样是一句话概括:
箭头函数里面根本没有自己的this,而是引用外层的this
我们先来理解一下这句话的上半部分,“ 箭头函数里面根本没有自己的this ”
箭头函数 () =>{ } 本质是个匿名函数funcion ( ) { } ,名为其实匿名函数设计之初
即为一次性用品故无需赋予其名字,因此其中的this的指向也只能取决于外部。
再来理解下半部分,“ 而是引用外层的this ”
,this只有在函数被调用,或者通过构造函数new Object()的形式才会有this
因此我们来看一下下面的两个例子的对比
第一个是对象,故里面没有this则箭头函数里面的this只能指向最外部的window,比如: (1) var obj = { a: () => { console.log(this) } } obj.a() //打出来的是window (2) function fn(){ a = 22 var b = ()=>{console.log(this.a)} b() } fn() //输出22
第二个是函数,故里面有this指向fn,因此箭头函数本身没有this,就直接继承其父执行上下文里面的this
***简单对象(非函数)是没有执行上下文的!***
- 同样是一句话概括:
-
3.我们也来总结一下箭头函数的
不适用场景
- (1) 构造函数中,因为箭头函数的this是在函数创建时就完成绑定的,无法跟随new出来的实例而改变
- (2) 在绑定交互事件的时候, eg : button.addEventListener( )
- (3) 当需要在函数中使用argument对象的时候