我正在尝试在 Array 对象的原型(prototype)上添加自定义方法:
Array.prototype.demo = function(){
this.forEach(i=>console.log(i))
}
但是,当我调用这样的方法时,我收到以下错误:
[1,2,3].demo()
// Error: TypeError: Cannot read property 'demo' of undefined
但是,当我将其更改为:
时,它运行成功const arr = [1,2,3];
arr.demo()
// Output: 1, 2, 3
PS。这是在nodejs中
要在浏览器中重现错误,请立即复制/粘贴整个 block ,然后单击 Enter。
更新:听起来我们需要添加一个分号才能使其工作:
Array.prototype.demo = function(){
this.forEach(i=>console.log(i))
}; <=== added semicolon here to work @jfriend00
[1,2,3].demo();
但是,现在下一个代码可以在没有分号的情况下运行!!
String.prototype.demo = function(){
this.split('').forEach(c=>console.log(c))
}
'hello'.demo();
最佳答案
快速修复 - 添加分号
在函数定义末尾添加分号:
Array.prototype.demo = function(){
this.forEach(i=>console.log(i))
}; // <======
[1,2,3].demo();
而且,它会起作用。
发生了什么事?
问题在于 [1,2,3]
正在与前一个函数组合(它们之间的空格被折叠)。在这种情况下,[1,2,3]
就变成 [3]
并尝试从函数对象读取 [3]
属性。如果将分号放在函数定义的末尾,则表示函数定义语句结束,并且 [1,2,3]
可以解释为静态数组定义。
一切都与上下文有关。在 Javascript 的某些情况下,[x]
是属性访问。在其他情况下,它是静态数组定义。如果没有分号,它将被解释为属性访问而不是数组定义。
请记住,函数是 Javascript 中的对象,因此它们可以具有属性,并且可以响应 [x]
作为对它们的属性访问。
因此,如果函数末尾没有分号,您基本上会得到以下结果:
Array.prototype.demo = function() {...}[3].demo();
因为函数末尾和 [1,2,3]
之间的空白被折叠。这意味着 JS 解释器期望 []
是一个属性名称,因此它会评估 []
内的语句,并在该上下文中 [1,2,3]
变成 [3]
(评估 1,2,3
,它采用最后一个逗号分隔语句的值,即 3
)。
更详细的说明
这样想:
// defines function
let f = function() {};
// attempts to read a property from that function object
let o = f [1,2,3]; // this is the same as let o = f[3]
// tries to call `.demo()` on the value read from that property
// which was undefined so this throws
o.demo();
函数就是对象
作为函数如何成为对象的演示,请参阅这个实际有效的示例!
// defines function
let f = function() {};
f[3] = {demo: function() { console.log("demo!!!");}}
// attempts to read a property from that function object
let o = f[1,2,3]; // this is the same as let o = f[3]
// tries to call `.demo()` on the value read from that property
// which was undefined so this throws
o.demo();
在这里,我们实际上在函数的 [3]
属性上放置了一个属性,因此当 f[1,2,3]
读取该属性时,它实际上获取了一个带有 .demo()
方法的对象,因此当我们调用它时,一切都有效。我并不是建议人们以这种方式进行编码,但我试图说明 f[1,2,3]
如何从函数对象中读取 [3]
属性。
不要省略分号的充分理由
这些奇怪的情况是不要省略分号的好理由,即使您通常(但并非总是)侥幸逃脱。
关于javascript - 在 Nodejs 中调用 Array 原型(prototype)上的自定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58964479/