控制台中输入console.log(this)来打印出来全局执行上下文中的 this,最终输出的是 window 对象。所以你可以得出这样一个结论:全局执行上下文中的 this 是指向 window 对象的。这也是 this 和作用域链的唯一交点,作用域链的最底端包含了 window 对象,全局执行上下文中的 this 也是指向 window 对象。
有下面三种方式来设置函数执行上下文中的 this 值。
- 通过函数的 call 方法设置
其实除了 call 方法,你还可以使用 bind 和 apply 方法来设置函数执行上下文中的 this
- 通过对象调用方法设置
使用对象来调用其内部的一个方法,该方法的 this 是指向对象本身的。
在全局环境中调用一个函数,函数内部的 this 指向的是全局变量 window。通过一个对象来调用其内部的一个方法,该方法的执行上下文中的 this 指向对象本身
- 通过构造函数中设置
我们使用 new 创建了对象 myObj,那你知道此时的构造函数 CreateObj 中的 this 到底指向了谁吗?
首先创建了一个空对象 tempObj;
接着调用 CreateObj.call 方法,并将 tempObj 作为 call 方法的参数,这样当 CreateObj 的执行上下文创建时,它的 this 就指向了 tempObj 对象;
然后执行 CreateObj 函数,此时的 CreateObj 函数执行上下文中的 this 指向了 tempObj 对象;
最后返回 tempObj 对象。
this 的设计缺陷以及应对方案
- 嵌套函数中的 this 不会从外层函数中继承
解决方法:使用箭头函数
原理:ES6 中的箭头函数并不会创建其自身的执行上下文,所以箭头函数中的 this 取决于它的外部函数。
- 普通函数中的 this 默认指向全局对象 window
不过这个设计也是一种缺陷,因为在实际工作中,我们并不希望函数执行上下文中的 this 默认指向全局对象,因为这样会打破数据的边界,造成一些误操作。如果要让函数执行上下文中的 this 指向某个对象,最好的方式是通过 call 方法来显示调用。
此文章为10月Day016学习笔记,内容来源于极客时间《浏览器原理与实践》,强烈推荐该课程