javascript - 有人可以告诉我为什么我不理解这个例子中的范围吗?

标签 javascript jquery

请原谅我——我是一名经验丰富的 Java 程序员,但仍在努力解决语言之间的语义差异!

我有一个小的 JavaScript 对象构造函数。它包括一个获取一小段 Ajax 数据的 jQuery 函数。当返回数据时,我想将其与对象构造函数顶部定义的变量 (renderMode) 结合使用,但可能是由于功能 block 关闭,我得到了“未定义”。

  1. 有人可以给我一段更正后的代码,它向我展示如何访问函数(数据)内部的 renderMode
  2. 几乎同样重要的是,有人可以向我解释为什么我所做的不起作用!

示例如下:

function AsyncRequest() {
    this.renderMode = RenderMode.NONE;
    this.setId = setId;

    function setId(v) {
        this.id = v;
    }
    this.setURL = setURL;

    function setURL(v) {
        this.URL = v;
    }

    this.render = render;

    function render(element) {
        $.get(
            this.URL,
            function (data) {
                // The data comes back just fine ...
                // ... and I know a value was previously assigned to renderMode
                // ... in this instance of AsyncRequest, but how do I get at it ?
                console.log("Render mode: " + this.renderMode); // this.renderMode is undefined
            }
        );
    }
}

最佳答案

与 Java 不同,JavaScript 中的 this 主要取决于函数的调用方式,而不是函数的定义位置。 (ES6 将添加一种方法来进行 this 词法绑定(bind),但目前它主要由函数调用绑定(bind)。)因此,您传递给 $.get 的回调被调用时 this 并未引用您期望的对象。

您可以通过使用闭包这一事实来解决这个问题:

function render(element) {
    var self = this;  // <=== Note
    $.get(
        this.URL,
        function (data) {
            console.log("Render mode: " + self.renderMode);
            // Note ----------------------^
        }
    );
}

在那里,我们记住了在名为 self 的变量中调用 render 时的 this 是什么(名称并不重要) ,然后利用回调函数是对 render 调用上下文的闭包这一事实,因此我们可以访问 self 变量。

你也可以用ES5的Function#bind来解决:

function render(element) {
    $.get(
        this.URL,
        function (data) {
            console.log("Render mode: " + this.renderMode); // this.renderMode is undefined
        }.bind(this) // <== Note
    );
}

Function#bind 返回一个函数,该函数在调用时会调用原始函数,并将 this 设置为您为其指定的值。

更多(在我的博客上):

关于javascript - 有人可以告诉我为什么我不理解这个例子中的范围吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21223260/

相关文章:

javascript - JQuery 父子选择

javascript - 当未选择文本区域时,如何使占位符显示?

jquery - 无法使平面 ui 标签正常工作

javascript - 添加多个包含html的选择器

javascript - 相对于容器的字体大小

javascript - 避免nodeJs中的回调 hell /将变量传递给内部函数

javascript - Angularjs:将对象参数传递给状态

php - 正则表达式匹配字符串中的所有 *texttexttext

javascript - 点击展开div

jQuery 片段用动画交换两组元素