javascript - 在 Nodejs 中调用 Array 原型(prototype)上的自定义方法

标签 javascript arrays node.js prototype

我正在尝试在 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/

相关文章:

javascript - 禁用 href 并执行函数

c - 将数组展平为字符串

arrays - 使用outer生成列表数组

javascript - Node : How to fix routing?

javascript - 使用爬虫查找多个网站的字体系列

javascript - nodeJS require.paths 解决问题

javascript - 我的网站 CSS 没有显示

javascript - 当必填字段为空时按钮被禁用

python - 按值和计数聚合,不同数组

node.js - 在 Cheerio 中使用 withStartIndices 选项时,element.startIndex 未定义