视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScript进阶系列—this的工作原理
2020-11-27 20:25:26 责编:小采
文档


  • 全局范围内

  • 函数调用

  • 方法调用

  • 调用构造函数

  • 显式的设置 this

  • 常见误解

  • 方法的赋值表达式

  • JavaScript 有一套完全不同于其它语言的对 this 的处理机制。 在五种不同的情况下,this 指向的各不相同。

    全局范围内

    this;

    当在全部范围内使用 this ,它将会指向全局对象。

    函数调用

    foo();

    这里 this 也会指向全局对象。

    方法调用

    test.foo();

    这个例子中, this 指向 test 对象。

    调用构造函数

    new foo();

    如果函数倾向于和 new 关键词一块使用,则我们称这个函数是 构造函数。 在函数内部,this 指向新创建的对象。

    显式的设置 this

    function foo(a, b, c) {}
    
    var bar = {};
    foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示
    foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3

    当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被显式设置为函数调用的第一个参数。

    因此函数调用的规则在上例中已经不适用了,在 foo 函数内 this 被设置成了bar。

    常见误解

    尽管大部分的情况都说的过去,不过第一个规则(译者注:这里指的应该是第二个规则,也就是直接调用函数时,this 指向全局对象) 被认为是JavaScript语言另一个错误设计的地方,因为它从来就没有实际的用途。

    Foo.method = function() {
     function test() {
     // this 将会被设置为全局对象(译者注:浏览器环境中也就是 window 对象)
     }
     test();
    }

    一个常见的误解是 test 中的 this 将会指向 Foo 对象,实际上不是这样子的。

    为了在 test 中获取对 Foo 对象的引用,我们需要在 method 函数内部创建一个局部变量指向 Foo 对象。

    Foo.method = function() {
     var that = this;
     function test() {
     // 使用 that 来指向 Foo 对象
     }
     test();
    }

    that 只是我们随意起的名字,不过这个名字被广泛的用来指向外部的 this 对象。 在 闭包 一节,我们可以看到 that 可以作为参数传递。

    注意: 在对象的字面声明语法中,this 不能用来指向对象本身。 因此 var obj = {me: this} 中的 me 不会指向obj,因为 this 只可能出现在上述的五种情况中。 译者注:这个例子中,如果是在浏览器中运行,obj.me 等于window 对象。

    方法的赋值表达式

    另一个看起来奇怪的地方是函数别名,也就是将一个方法赋值给一个变量。

    var test = someObject.methodTest;
    test();

    上例中,test 就像一个普通的函数被调用;因此,函数内的 this 将不再被指向到 someObject 对象。

    虽然 this 的晚绑定特性似乎并不友好,但这确实是基于原型继承赖以生存的土壤。

    function Foo() {}
    Foo.prototype.method = function() {};
    
    function Bar() {}
    Bar.prototype = Foo.prototype;
    
    new Bar().method();

    当 method 被调用时,this 将会指向 Bar 的实例对象。

    下载本文
    显示全文
    专题