【问题标题】:Losing "this" context in JavaScript when passing around members [duplicate]传递成员时在JavaScript中丢失“this”上下文[重复]
【发布时间】:2015-05-27 15:06:13
【问题描述】:

我有一个简单的 JSFiddle here 来演示我的问题。

我有这个 JavaScript 代码:

var b = document.getElementById("b");

function A() {
    this.f = "1";
}

A.prototype.t = function() {
    b.innerHTML = this.f;
};

var a = new A();

var l = a.t;
l();

当我尝试调用 a.t 时,为什么 this 未定义?如何在不过度冗长或存储过多的情况下恢复该上下文?

【问题讨论】:

标签: javascript


【解决方案1】:

为什么当我尝试调用 a.t 时这是未定义的?

因为在 JavaScript 中,this 主要由函数的调用方式设置,而不是在哪里定义。 a.t() 在调用中将this 设置为a,但l()this 设置为undefined(严格模式)或全局对象(松散模式)。

更多(在我的博客上)

唯一的例外是“绑定”函数(如 Function#bind)或 ES6 的“箭头”函数(从定义它们的上下文中获取它们的 this)。

如何恢复该上下文而不会过于冗长或存储太多?

Function#bind 通常是一个很好的答案:

var l = a.t.bind(a);
l();

它返回一个新函数,当调用该函数时,会调用原始函数并将 this 设置为您提供的第一个参数 bind。 (您也可以绑定其他参数。)它是一个 ES5 函数,但如果您需要支持非常旧的浏览器,您可以轻松地对其进行 polyfill。


如果您只需要调用 l 使用特定的this 值,而不是总是使用该值,如Robert Rossmann points out,您可以使用Function#callFunction#apply

l.call(this, 'a', 'b', 'c');    // Calls `l` with `this` set to `a` and args 'a', 'b', and 'c'
l.apply(this, ['a', 'b', 'c']); // Calls `l` with `this` set to `a` and args 'a', 'b', and 'c' -- note they're specified in an array

【讨论】:

  • 或者,如果函数不需要传递并且只需要调用一次,可以使用Function.prototype.callvar l = a.t; l.call(a);
  • 关于原始询问者的代码,如果在原始A 函数中定义A.t() 是否有效?这样,函数就可以访问私有范围的变量 (like this)。
  • @RobertRossmann 你能证明一下吗?
  • @eatonphil: l.call(a) 将调用l 并将this 设置为a
  • @JeffNoel:是的。不会是this,但是是的。然而,它可能“保留太多”。
【解决方案2】:

JavaScript 在功能范围内,

要执行具有正确值的函数,您需要将其绑定到正确的对象。例如,

var l= a.t.bind(a);

【讨论】:

  • 但是绑定上下文与作用域并没有真正的关系。
【解决方案3】:

因为当您将函数分配给新变量时,上下文会发生变化。你总是可以做a.t();

【讨论】:

    猜你喜欢
    • 2015-05-28
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 2020-09-18
    相关资源
    最近更新 更多