为什么
function Example() {
this.go();
}
Example.prototype.go = function() {
console.log("going");
}
(new Example());
对我说this.go不是一个函数,而
function Example() {
this.go();
}
Example.prototype.go = function() {
console.log("going");
}
new Example();
是否按预期正确记录?
执行环境是macOS High Sierra 10.13.4上的节点v10.4.1
答案 0 :(得分:3)
您依赖ASI,它无法按您期望的方式工作。
在第一个示例中,()
将您尝试分配给Example.prototype.go
的函数表达式转换为IIFE。
因此,事件的顺序是:
Example
已定义new Example()
得到评估undefined
)的返回值已分配给Example.prototype.go
…,但是由于在该点未定义go
,因此在第2步出错。
为了避免这种情况,请在每个语句的末尾使用明确的分号。
答案 1 :(得分:2)
这是因为您依赖自动分号插入(ASI)(可能是无意的),而且还以(
开始。如果您使用;
正确终止了分配,则问题将消失:
function Example() {
this.go();
}
Example.prototype.go = function() {
console.log("going");
}; // <==== ; here
(new Example());
问题是没有 ;
,赋值后的()
表达式和其前面的function() { }
表达式在语法上结合在一起-(但不是逻辑上有效的方式):它调用函数,并传递new Example
的结果。因此ASI不会介入。
如果您不是故意依赖ASI,只需注意赋值表达式需要以;
结尾。
如果您有意依赖ASI,则由于这个原因,您必须以主动(
开始以[
或;
开头的行。因此,在您的情况下:
function Example() {
this.go();
}
Example.prototype.go = function() {
console.log("going");
}
;(new Example());
// ^----
答案 2 :(得分:1)
问题是您在分配给.go
的函数 expression 后忘记了分号:
Example.prototype.go = function() {
console.log("going");
} // <--- no semicolon!
(new Example());
以下行带有开括号()-因此,解释器认为您正在立即调用上述函数:
Example.prototype.go = function() {
console.log("going");
}(new Example());
这是在 被分配给Example.prototype.go
之前发生的-解释器试图在将结果分配给{{1}之前将表达式的右侧求值}。但是,您是在Example.prototype.go
被填充之前打电话给new Example()
。因此,Example.prototype.go
是this.go
。
只需在undefined
后面加上分号即可:
}