概念:一般指向调用它的对象。
如何理解这句话:
-
首先,this指向的应该是一个对象,更具体地说是函数执行的“上下文对象”;
-
其次,这个对象指的是“调用它”的对象,如果调用它的不是对象或对象不存在,则指向全局对象(严格模式下为undefined)。
-
改变this指向的常见3种方式:bind、call和apply。
-
举例说明:
var o = {fn() { console.log(this) } } o.fn() // ofunction fn() {console.log(this)} function fn2() {fn()} fn2() // window(Node.js 下是 global)
function fn() {console.log(this)} function fn2() {fn()} var obj = {fn2} obj.fn2() // ? // 需要注意,调用函数 fn() 的是函数 fn2() 而不是 obj。虽然 fn2() 作为 obj 的属性调用,但 fn2()中的 this 指向并不会传递给函数 fn(), 所以答案也是 window(Node.js 下是 global)
var dx = { arr: [1] } dx.arr.forEach(function() {console.log(this)}) // ? forEach它有两个参数,第一个是回调函数,第二个是 this 指向的对象,这里只传入了回调函数,第二个参数没有传入,默认为 undefined,所以正确答案应该是输出全局对象。
class B { fn() { console.log(this) } } var b = new B() var fun = b.fn fun() // ? ES6 下的 class 内部默认采用的是严格模式,而严格模式下不会指定全局对象为默认调用对象,所以答案是 undefined。
var arrow = {fn: () => { console.log(this) }} arrow.fn() // 全局对象
ES6 新加入的箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this。可以简单地理解为箭头函数的 this 继承自上层的 this,但在全局环境下定义仍会指向全局对象。
var arrow = {
fn() {
const a = () => console.log(this)
a()
}
}
arrow.fn() // arrow
[0].forEach(function() {console.log(this)}, 0) // ?
// this 指向的是一个值为 0 的 Number 类型对象。