为什么使用Javascript;“类型错误”;

为什么使用Javascript;“类型错误”;,javascript,Javascript,这将执行以产生正确的结果,Chrome调试器表示没有异常: var x = new Foo().bar().baz(); 但这会进入空格,永远不会完成,Chrome调试器说,尽管bar()执行正确,但它会抛出一个“typeerror”异常,并且在尝试调用baz()时永远不会到达指定的函数: 在我看来,它们在功能上是一样的。为什么它们的行为不同?您需要括号: var x = (new Foo()).bar().baz(); 否则,new语句将应用于Foo().bar().baz()的返回值,所

这将执行以产生正确的结果,Chrome调试器表示没有异常:

var x = new Foo().bar().baz();
但这会进入空格,永远不会完成,Chrome调试器说,尽管bar()执行正确,但它会抛出一个“typeerror”异常,并且在尝试调用baz()时永远不会到达指定的函数:

在我看来,它们在功能上是一样的。为什么它们的行为不同?

您需要括号:

var x = (new Foo()).bar().baz();
否则,
new
语句将应用于
Foo().bar().baz()
的返回值,所有这些都将在尝试实例化之前执行


更新:我注意到,正如他们所说,这是错误的。但我认为这些评论很有趣,所以我不会删除答案。

似乎与Chrome调试器有关:

function Foo(){}

Foo.prototype.bar = function() {
  return this;
}

Foo.prototype.baz = function() {
  return 'baz';
}

var x = new Foo().bar().baz();
console.log(x); // baz
如期而至(Firefox、IE、Chrome)

编辑 而且:

var x = new Foo();
x = x.bar().baz()
console.log(x); // baz

这两套代码在功能上是相同的。

回答了我自己的问题——我真的觉得自己很笨!很抱歉“他们为什么表现不同?”——他们没有

出于让其他人尝试同样的事情但得到不同的结果的动机,我进一步思考了我的问题,最终发现……一个打字错误!在camelcase中,我建模为“baz()”的函数的原始名称是一个冗长的字符串,并且出现了一个错误大小写的ell('l')

事实证明,调试器是一种骗人的东西。(我只使用它们来跟踪执行和显示错误消息,而不是评估任何东西或模拟环境。)

如果错误消息更直接,我希望能更快地发现真正的问题。Chrome调试器报告抛出了一个“typeerror”,Firebug报告了一个“无效的作用域变量”,这两个变量都没有让我在函数名中查找输入错误


经验教训:不要在午夜后发布问题:-)

是否返回
?执行此操作时,第一个函数做什么:
var x=(new Foo()).bar().baz()?更多关于
Foo
.bar()
.baz()
的定义和实现将使我们更清楚地了解正在发生的事情。一个简单的JSFIDLE可以让我们清楚地了解这两种情况。这两种情况在这里都没有问题:我认为您需要给我们一个更具体的示例,说明您在
Foo
bar
baz
中使用了什么。或者给我们看一个复制这个问题的JSFIDLE怎么样?这个问题似乎离题了,因为它是关于打字错误的DRight-Chrome调试器可能需要
操作符绑定比
new
-1更紧密,但ECMAScript中不需要它。那么谁是对的,@pointy,还是RobG?@AdamRackis请看我的答案,在Firefox、IE和Chrome中测试过。我对挖掘规范的相关部分并不感兴趣,我怀疑它是从这里开始的:@AdamRackis我认为RobG就在这里-与
new
相比,有趣的不是
操作符,而是函数调用(构造函数名称后的括号)。那么,您的示例在什么环境下成功?@nrabinowitz这将在控制台和
中工作。我对规范的阅读表明
新的
不会比
绑定得更紧密,但我对此不太有信心。我太懒了,啤酒太多了,现在不想尝试。实际上现在编辑我认为我错了。它是从左到右求值的,根据:
newmemberexpression参数
->
CallExpression。IdentifierName
->
调用表达式。IdentifierName
->
调用表达式
。或者类似的东西。OP已经说过,
newfoo().bar().baz()
按照他所期望的那样工作。您还没有解决导致他出错的代码,我看不出这是如何回答他的问题的。
var x = new Foo();
x = x.bar().baz()
console.log(x); // baz