gpt4 book ai didi

javascript - 为什么在为 Javascript 原型(prototype)定义函数时,函数名称会出现在 for 循环中?

转载 作者:行者123 更新时间:2023-12-01 02:59:02 24 4
gpt4 key购买 nike

我对 Javascript 及其无限的伟大之处还比较陌生。我想练习为对象原型(prototype)定义自己的函数,因此我练习为 Array 编写一个 contains() 函数:

if (!Array.prototype.contains){
Array.prototype.contains = function(target){
for (var i in this){
console.log(i);
if (this[i] == target) return true;
}
return false;
}
}

本质上,contains() 会遍历 this 内的每个元素来查找目标。但是,我注意到 console.log(i) 返回索引号(即 012 等)如预期取决于数组内的元素数量。然而,它也总是打印出contains!这是我的 console.log 的输出,数组中只有一个元素:

0
contains

但是,如果我更改迭代 for 循环的方式,我不会得到 contains 输出:

if (!Array.prototype.contains){
Array.prototype.contains = function(target){
for (var i = 0; i < this.length; i++){
console.log(i);
if (this[i] == target) return true;
}
return false;
}
}

输出:

0

现在我已经读完这篇文章StackOverflow post解释在数组迭代中使用 for...in 的危险,但我无法以编程方式解释为什么 contains 出现在我的第一个代码片段中。如果我在 Firefox 开发者控制台上使用 console.log(this),我会按预期收到一个 Array 对象:

Array [ "scrubBackButton2", "scrubNextButton1" ]

数组对象的最后一个元素是否始终是调用函数的名称?

我主要通过反复试验来学习 JS,所以如果我不知何故错过了一个好的答案,请务必向我推荐一份好的文档或之前的 SO 帖子!

最佳答案

for ... in 循环将遍历对象的每一个可枚举属性。因此它将遍历 ['1'] 属性和 ['2'] 属性等。数组具有的属性中有一个名为 ['包含']。为什么会有这样的东西呢?因为你把它放在那里! :)

或者更准确地说,你把它放在它的原型(prototype)上。但就 for ... in 而言,这几乎是相同的。它将循环遍历对象上的所有可枚举属性,以及它从其原型(prototype)继承的可枚举属性,以及从其原型(prototype)的原型(prototype)等继承的可枚举属性。 Array.prototype 上有很多属性,但它们不是可枚举的(这是为什么它没有同时注销“push”、“pop”、“map”等)。您放在那里的属性是可枚举的,因为这是属性的默认性质。

正如您所指出的,for ... in 不适合遍历数组,因此我建议更改代码以执行其他操作。例如,可以是手动 for 循环、this.forEachfor ... of

此行下面是一些其他选项,但它们会涉及一些您很少编写的代码(但话又说回来,修改 Array.prototype 是您很少会做的事情)。

========

如果您想保留 for ... in 循环,一种选择是显式检查以确保您正在查看的每个属性都来自对象本身,而不是来自其对象原型(prototype)。为此,您可以使用 hasOwnProperty。如果属性来自原型(prototype),hasOwnProperty 将返回 false。如果该属性属于该特定对象,则返回 true;

if (!Array.prototype.contains){
Array.prototype.contains = function(target){
for (var i in this){
if (!this.hasOwnProperty(i)) continue;
console.log(i);
if (this[i] == target) return true;
}
return false;
}
}

[1, 2].contains(5)

另一种可能性是使 contains 不可枚举。通过这样做,for ... in 循环将跳过它(Object.keys() 也会跳过它)

if (!Array.prototype.contains){
function contains(target){
for (var i in this){
console.log(i);
if (this[i] == target) return true;
}
return false;
}

Object.defineProperty(Array.prototype, 'contains', {
enumerable: false,
configurable: false,
writeable: false,
value: contains
});
}

[1, 2].contains(5);

有关定义属性的更多信息,请参阅此页面:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

关于javascript - 为什么在为 Javascript 原型(prototype)定义函数时,函数名称会出现在 for 循环中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46555412/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com