8

我有一个简单的JSFiddle在这里演示我的问题。

我有这样的JavaScript代码:

var b=文档.getElementById(“b”);函数A(){f=“1”;}A.prototype.t=函数(){b.innerHTML=this.f;};var a=新a();var l=a.t;l();

为什么是当我试图呼叫a.t时未定义?如何在不过分冗长或存储太多的情况下恢复该上下文?

1

3个答案

重置为默认值
15

为什么当我试图呼叫a.t时,这个没有定义?

因为在JavaScript中,主要由设置如何调用函数,而不是定义它的地方。a.t()在通话中,但是l()要么到未定义(在严格模式下)或全局对象(在宽松模式下)。

更多(在我的博客上):

唯一的例外是“绑定”函数(与函数#bind)或ES6的“箭头”功能从定义它们的上下文中)。

如何在不过分冗长或存储太多的情况下恢复该上下文?

函数#bind通常是一个好答案:

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

它返回一个新函数,当调用该函数时,使用设置为你给出的第一个参数绑定。(你也可以绑定其他参数。)这是一个ES5函数,但如果你需要支持非常旧的浏览器,你可以很容易地对它进行polyfill。


如果你只是需要呼叫 具有特定的值,并且不总是让它使用该值罗伯特·罗斯曼指出你可以使用函数#调用函数#应用:

l.call(this,'a','b','c');//调用`l`时将`this`设置为`a`,参数为'a'、'b'和'c'l.apply(this,['a','b','c']);//调用`l`并将`this`设置为`a`和args'a'、'b'和'c',注意它们是在数组中指定的
5
  • 1
    或者,可以使用函数.prototype.call如果函数不需要传递,只需要调用一次:var l=a.t;l.调用(a); 2015年5月27日15:14
  • 关于原始提问者的代码,如果A.t()在原始文件中定义A类功能?这样,函数就可以访问私有范围的变量(这样地). 2015年5月27日15:15
  • @罗伯特·罗斯曼,你能证明一下吗? 2015年5月27日15:15
  • @伊顿菲尔:l.调用(a)将呼叫具有设置为. 2015年5月27日15:21
  • 1
    @杰夫·诺埃尔:是的。不会的,但是的。可以然而,要“保留太多”。 2015年5月27日15:21
1

JavaScript具有功能范围,

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

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

因为将函数赋给新变量时,上下文会发生变化。你可以一直这样做a.t();.

不是你想要的答案吗?浏览标记的其他问题问自己的问题.