美文网首页
JavaScript 中的 this 关键字

JavaScript 中的 this 关键字

作者: 显卡84du | 来源:发表于2018-02-04 23:23 被阅读9次

    与其他语言相比,函数的 this 关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别。

    在绝大多数情况下,函数的调用方式决定了this的值。this不能在执行期间被赋值,并且在每次函数被调用时this的值也可能会不同。ES5引入了bind方法来设置函数的this值,而不用考虑函数如何被调用的,ES2015 引入了支持this词法解析的箭头函数(它在闭合的执行上下文内设置this的值)。

    作为 JavaScript 中一个最扑朔迷离的关键字,this 也成为面试中最受考官欢迎并使用的一个考点。看了一些文章后,你可能越看越迷糊,这很正常。不过今天我以 MDN 的文档库为基础,把一些学习心得记录一下。

    定义

    this 是函数作用域中自动生成的特殊的标识符关键字,可以将它当作一个指针来理解。

    不同环境下的 this 指向

    按照 ECMAScript 规范我们讨论两种常用可执行代码(上下文环境):

    • 全局代码(Global code)
    • 函数代码(Function code)

    1、全局上下文

    无论是否在严格模式下,在全局执行上下文中(在任何函数体外部)this 都指代全局对象。

    // 在浏览器中, window 对象同时也是全局对象:
    console.log(this === window); // true
    
    a = 37;
    console.log(window.a); // 37
    
    this.b = "MDN";
    console.log(window.b)  // "MDN"
    console.log(b)         // "MDN"
    

    2、函数上下文

    在函数内部,this 的值取决于函数被调用的方式。以下我们简单讨论三种。

    2.1 简单调用

    因为下面的代码不是在严格模式下执行,且 this 的值不是通过调用设置的,所以 this 的值默认指向全局对象。

    function f1(){
      return this;
    }
    // 在浏览器中:
    f1() === window;   // 在浏览器中,全局对象是window
    
    // 在Node中:
    f1() === global;
    

    然而,在严格模式下,this 将保持他进入执行上下文时的值,所以下面的this将会默认为 undefined

    function f2(){
      "use strict"; // 这里是严格模式
      return this;
    }
    
    f2() === undefined; // true
    

    所以,在严格模式下,如果 this 未在执行的上下文中定义,那它将会默认为 undefined

    2.2 作为对象的方法

    当以对象里的方法的方式调用函数时,它们的 this 是调用该函数的对象。

    var o = {
      prop: 37,
      f: function() {
        return this.prop;
      }
    };
    
    console.log(o.f()); // logs 37
    

    我们也可以首先定义函数,然后再将其附属到 o.f。这样做会导致相同的行为,也就是说,这样的行为不受函数定义方式或位置的影响。

    var o = { prop: 37 };
    
    function independent() {
      return this.prop;
    }
    
    o.f = independent;
    
    console.log(o.f()); // logs 37
    

    类似的,this 的绑定只受最靠近的成员引用的影响。

    o.b = { g: independent, prop: 42 };
    console.log(o.b.g()); // 42
    

    2.3 作为构造函数

    当一个函数用作构造函数时(使用 new 关键字),它的 this 被绑定到正在构造的新对象。

    简单总结

    最后,引用知乎的几个简单论断:

    • this 永远指向函数运行时所在(最近)的对象,而不是函数被创建时所在的对象;
    • 如果是 callapplywith,指定的 this 是谁,就是谁;
    • 普通的函数调用,函数被谁调用,this 就是谁。

    参考

    1、根治JavaScript中的this-ECMAScript规范解读
    2、你不懂JS: this 与对象原型 - this 是什么?
    3、你不懂JS: this 与对象原型 - 第二章: this 豁然开朗!
    4、JS 中 this 关键字详解
    5、彻底理解js中this的指向,不必硬背
    6、用自然语言的角度理解JavaScript中的this关键字

    相关文章

      网友评论

          本文标题:JavaScript 中的 this 关键字

          本文链接:https://www.haomeiwen.com/subject/wgwmzxtx.html