在javascript中,向Array.prototype添加新方法。

7

我是JavaScript语言的新手,最近开始研究JS原型,并对下面代码中的一些奇怪输出感到困惑:

Array.prototype.print = function() {
  console.log(this)
}

[1, 2, 3, 4].print();

有人能告诉我为什么会返回

'Cannot read property 'print' of undefined'

如果我声明 var array = [1, 2, 3, 4] ,然后通过 array.print() 调用 print 函数,它可以正常工作,所以我很困惑这两者有什么不同?

Array.prototype.print = function() {
  console.log(this)
}

var array = [1, 2, 3, 4]
array.print()


你同时运行了这两个代码块吗?当我分别运行每个代码块时,它可以正常工作,这表明存在竞态条件。确保第一个函数在调用最后一行之前已经运行。 - Jamie Weston
2个回答

6
你可以通过添加分号来分隔对函数的访问。
你所拥有的是使用逗号运算符对函数表达式进行属性访问,该访问返回4。在这种情况下,ASI(自动分号插入)不起作用。
Array.prototype.print = function() {
  console.log(this)
}[1, 2, 3, 4] //.print();   // tries to get property 4 of the function
                            // and then tries to call a function from undefined

函数表达式的块语句后需要加上分号。

Array.prototype.print = function() {
  console.log(this)
};

[1, 2, 3, 4].print();


是的,一旦我在print函数后面添加了分号,输出就正确了,也没有出现任何错误。非常感谢你! - chen.w
你能添加这段代码吗? - Nina Scholz
String.prototype.print = function() { console.log(this) }'chen'.print(); 对于这个,不会抛出任何错误; - chen.w
明白了,现在我完全理解了 JavaScript 中的这个概念,谢谢! - chen.w
有趣。数万行代码后,这种语言仍然用表面上基本的语法原则让我感到惊讶。 - ThisClark
显示剩余2条评论

1

如果您一次性运行整个代码块,则不能保证最后一行在第一块之后运行。

分别运行这两个块将突出显示这种差异,您将看到第二个块的正确输出。

先运行此代码:

Array.prototype.print = function() {
  console.log(this)
}

然后运行这个:
[1, 2, 3, 4].print();

有几种方法可以使它们异步运行。其中一种简单的方法是在最后一行中包装一个setTimeout(根据您的使用情况,这可能不合适)。

例如:

Array.prototype.print = function() {
  console.log(this)
}

setTimeout(()=> { 
    [1, 2, 3, 4].print();
}, 1000)


谢谢您的解决方案,它是完全正确的。有点奇怪的是js将这两个语句强制合并并同时运行。 - chen.w

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接