首先看一段代码
this两个方法中, 一个使用了 this,一个没有使用而是 显式 传入一个上下文对象。
this 提供了一种更优雅的方式来 隐式 “传递”一个对象引用,因此可以将 API 设计 得更加简洁并且易于复用。
JS 中的 this 是什么
我们知道 执行上下文中 包含了:变量环境、词法环境、outer,其实 还包含了一个 this。
执行上下文执行上下文 分三种: 全局执行上下文,函数执行上下文 和 eval 执行上下文,所以 this 也就分为了三种: 全局上下文中的 this, 函数执行上下文中的 this, eval 执行上下文中的 this。
全局执行上下文中的 this
我们知道,在 浏览器中 console.log(this) 结果 是 window 对象,所以 全局执行上下文中的 this 是指向 window 对象的。这也是 this 和作用域 链的唯⼀交点,作用域链的最底端包含了 window 对象。
函数执行上下文中的 this
this 指向 window默认情况下 调用函数, 它的执行上下文的 this 也是指向 window 对象的,那么如何改变 函数执行上下文中的 this 。
1. call、apply、 bind
文中最上面的例子就是通过 call 来改变 this 的 指向, apply 和 bind 用法类似
2. 通过对象调用方法
1使用对象来调用其内部的⼀个方法,该方法的 this 是指向对象本身的。
但是执行 下面一段代码, this 又指向了 window。
2总结:在全局环境中调用一个函数,函数内部的this指向的是全局变量 window; 通过⼀个对象来调用其内部的⼀个方法,该方法的执行上下⽂中的 this 指向对象本身。
3 构造函数设置 this
当执行 new 操作符的时候, JS 引擎做了以下事情:
1⾸先创建了⼀个空对象 tempObj;
2 接着调用 Student.call ⽅法,并将 tempObj 作为 call ⽅法的参数,这样当 Student 的执行上下文创建 时,它的 this 就指向了 tempObj 对象;
3 然后执行 Student 函数,此时的 Student 函数执行上下文中的 this 指向了 tempObj 对象;
4 最后返回tempObj对象 。
this 应用中出现的问题
1. 嵌套函数中的 this 不会从外层函数中继承
3sayAge 中的 this 指向全局 , 而 sayHello 中的 this 指向 obj 对象。
解决方法:
1 把 this 保存为⼀个 that 变量,再利用变量的作用域机制传递给嵌套函数。
2 es6 的箭头函数,把嵌套函数改为箭头函数,因为箭头函数没有自己的执行上下文,所以 会继承调⽤函数中的 this。
4总结
1. 当函数被正常调用时(如 foo()),在严格模式下,this值是undefined,非严格模式下 this 指向的是全局对象 window;
2. 当函数作为对象的方法调用时(如 obj.foo()),函数中的 this 就是该对象;
3. 嵌套函数中的 this 不会继承外层函数的 this 值。
4. 箭头函数没有自己的执行上下文,所以箭头函数的 this 就是它外层函数的 this。
网友评论