zoukankan      html  css  js  c++  java
  • 老生常谈,JavaScript闭包中的this对象

    我们知道,this 对象是在运行时基于函数的执行环境绑定的:在全局函数中, this 等于 window,而当函数被作为某个对象的方法调用时, this 于那个对象。

    不过,匿名函数的执行环具有全局性,因此其 this 对象通常指向 window。但有时候由于编写闭包的方式不同,这一点可能不会那么明显。下面来看一个例子。

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function() {
            return function() {
                return this.name;
            };
        }
    };
    alert(object.getNameFunc()()); //"The Window"(在非严格模式下)

    以上代码先创建了一个全局变量 name,又创建了一个包含 name 属性的对象。这个对象还包含一个方法——getNameFunc(),它返回一个匿名函数,而匿名函数又返回 this.name。由于 getNameFunc()返回一个函数,因此调用 object.getNameFunc()()就会立即调用它返回的函数,结果就是返回一个字符串。然而,这个例子返回的字符串是"The Window",即全局 name 变量的值。为什么匿名函数没有取得其包含作用域(或外部作用域)的 this 对象呢?

    前面曾经提到过,每个函数在被调用时都会自动取得两个特殊变量: this arguments内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变。不过,把外部作用域中的 this 对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了,如下所示。

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function() {
            var that = this;
            return function() {
                return that.name;
            };
        }
    };
    alert(object.getNameFunc()()); //"My Object"

    代码中突出的行展示了这个例子与前一个例子之间的不同之处。在定义匿名函数之前,我们把 this对象赋值给了一个名叫 that 的变量。而在定义了闭包之后,闭包也可以访问这个变量,因为它是我们在包含函数中特意声名的一个变量。即使在函数返回之后, that 也仍然引用着 object,所以调用object.getNameFunc()()就返回了"My Object"

    在几种特殊情况下, this 的值可能会意外地改变。比如,下面的代码是修改前面例子的结果。

    var name = "The Window";
    var object = {
        name: "My Object",
        getName: function() {
            return this.name;
        }
    };

    这里的 getName()方法只简单地返回 this.name 的值。以下是几种调用 object.getName()方式以及各自的结果。

    object.getName(); //"My Object"

    (object.getName)(); //"My Object"

    (object.getName = object.getName)(); //"The Window",在非严格模式下

    第一行代码跟平常一样调用了 object.getName(),返回的是"My Object",因为 this.name就是 object.name。第二行代码在调用这个方法前先给它加上了括号。虽然加上括号之后,就好像只是在引用一个函数,但 this 的值得到了维持,因为 object.getName (object.getName)的定义是相同的。第三行代码先执行了一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以 this 的值不能得到维持,结果就返回了"The Window"

    当然,你不大可能会像第二行和第三行代码一样调用这个方法。不过,这个例子有助于说明即使是语法的细微变化,都有可能意外改变 this 的值。

  • 相关阅读:
    LeetCode 326. Power of Three
    LeetCode 324. Wiggle Sort II
    LeetCode 322. Coin Change
    LeetCode 321. Create Maximum Number
    LeetCode 319. Bulb Switcher
    LeetCode 318. Maximum Product of Word Lengths
    LeetCode 310. Minimum Height Trees (DFS)
    个人站点大开发!--起始篇
    LeetCode 313. Super Ugly Number
    LeetCode 309. Best Time to Buy and Sell Stock with Cooldown (DP)
  • 原文地址:https://www.cnblogs.com/guiren/p/5209695.html
Copyright © 2011-2022 走看看