普通函数中的this:
1. this总是代表它的直接调用者(js的this是执行上下文), 例如 obj.func ,那么func中的this就是obj
2.在默认情况(非严格模式下,未使用 'use strict'),没找到直接调用者,则this指的是 window (约定俗成)
3.在严格模式下,没有直接调用者的函数中的this是 undefined
4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象
箭头函数中的this
1.箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),此处指父级作用域,而不是执行时的对象, 定义它的时候,可能环境是window; 箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this
2.箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。
例如这段函数中,this指向的是Person对象,可以看到控制台打印结果,此时的箭头函数所处的宿主对象是Person,所以this指向的是person
看下面这段js代码,
此时的箭头函数所处的宿主对象是window对象,所以此处的this指向的是window。
再看下面这段代码,这是写在react中的一段箭头函数,这个箭头函数所处的对象是MainForm这个类,所以在调用之后输出的就是MainForm这个对象
综上:箭头函数没有自己的this,它的this是继承而来,默认指向在定义它时所处的对象(宿主对象)。
下面看这样一段代码,非箭头函数,
可以看到这里的this指向的是window对象,这是由于setInterval跟setTimeout调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。详细可参考MDN setTimeout MDN setInterval
下面我们做一个修改,将this存为一个变量,此时的this指向Person1,也可以使用bind函数来绑定this实现以下效果
对于评论区的使用方式做一解释,
var s = 21;
const obj = {
s: 42,
m: () => console.log(this.s),
k: function(){console.log(this.s)}
};
obj.m(); // 21
obj.k(); // 42
obj.m() //21 是因为obj的m是箭头函数,箭头函数的this是定义时所处的对象,即它的父级作用域,所以此处是21
obj.k() // 42 普通函数,所以指向它的直接调用者,即obj调用k,所以this指向k,所以此处是42
其他有关this详解可参考这个博客:this指向详解