对象/数组和循环上的原型
prototypes on objects/arrays and loops
今天出现了一个奇怪的错误。在我们的应用程序中,在一个文件上,所有对象都附加了一个函数,就好像它们是原型一样。我们没有对我们的数组进行原型设计,但我已经研究过其他一些东西,其中数组和对象有原型,当你做for(this in that)循环时,原型会作为项目包括在内,我们必须对它们进行过滤。因此,由两部分组成的问题:
-
如果你为你的数组制作原型,索引会增加+#个原型吗?所以,如果数组(a,b,c)有array.protype.function(),它的索引计数是3还是4?
-
这种情况应该发生吗?
我们认为我们拥有的一个jquery插件是邪恶的。
我认为"index count"是指length
属性。在这种情况下,第一个问题的答案是"否"。length
属性与数组的最高数字索引绑定。例如,如果您有以下代码,arr.length
将是4
:
var arr = [];
arr[3] = true;
arr.length; //is 4
然而,您提到了in循环,在这种情况下,它有奇怪的行为。如果我们在arr
上执行for in(从上面),我们会得到以下结果:
var output = "";
for (i in arr) { //Don't do this!
output += i;
}
output; //is "3" (not "0123" as you might expect)
正如我提到的,原型化属性对长度没有影响:
Array.prototype.foo = true;
var arr = [];
arr[3] = true;
arr.length; //is 4
然而,它们确实会影响内循环(在正常情况下):
var output = "";
for (i in arr) { //arr from the previous code block.
output += i;
}
output; //is "3foo" (or maybe "foo3", there's no guarantee form the spec either way)
有几种方法可以解决这个问题。首先,你真的不应该在数组中使用for对象,因为这是无稽之谈。但是,如果出于某种原因必须这样做,您应该始终使用hasOwnProperty()
过滤器来保护for in loop,如下所示:
var output = "";
for (i in arr) { //arr from the previous code block
if (arr.hasOwnProperty(i)) {
output += i;
}
}
output; //is "3"
同样,不能保证在中的上订购 另一种选择是,通过使用ES5的功能(如果存在),通过将原型化属性设置为不可枚举,来保护对象级别上的原型化属性,从而避免他人的错误编码。你可以这样做: 我再怎么强调也不为过,在数组上执行for是个坏主意。事实上,在几乎所有情况下,我都倾向于避免使用In,因为你永远不知道是否有人想成为一个混蛋,并会把它扔到他们的代码中间:var foo = (function() { /* do something */ });
if(typeof Object.defineProperty === "function") { //If ES5
Object.defineProperty(Array.prototype, "foo", {
value: foo,
enumerable: false //make it not enumerable
});
} else { //For older browsers
Array.prototype.foo = foo;
}
var arr = [], output = "";
arr[3] = true;
for(i in arr) { //Seriously, don't do this.
output += i;
}
output; //is "3"
Object.prototype.ponies = "Ponies!";
尽管数组是对象,因此可以有多个属性,但只有整数属性计入array
本身。
var a = [];
alert(a.length); // 0
a.foo = "Ha";
alert(a.length); // 0
a[1] = 10;
alert(a.length); // 1
Array.prototype.shuffle = function() { ... }
alert(a.length); // 1
虽然不建议使用for ... in
来处理数组,但有些人仍然这样做。for ... in
会同时找到foo
和shuffle
。
如果您避免使用for (var i in array)
来迭代您的数组,并且只通过从0到array.length - 1
的数字索引来迭代它们,那么如果有人向数组原型添加了一些东西,您就不会有问题。这正是您应该避免使用for/in
技术来迭代数组的原因。
无论向数组或数组原型添加了多少属性或方法,迭代数组的一些安全方法:
for (var i = 0, len = array.length; i < len; i++) {
// access array[i] here
}
var i = 0, len = array.length;
while (i < len) {
// access array[i] here
i++;
}
- 为什么要返回'这'在导致循环的JavaScript原型中
- 对象/数组和循环上的原型
- 在for循环中设置断点会导致在数组上使用原型时出错
- 循环遍历数组时的原型对象
- 向对象原型添加函数会导致函数显示在所有“OBJ 中的 X”循环中
- for (数组中的键)循环遍历数组原型
- 如何循环访问对象的原型属性
- 为什么在 javascript 中向数组原型添加方法会破坏 for 循环上的迭代
- 为什么“for-in”循环不会循环访问原型属性
- 为..在循环和原型链中
- 数组上的 for.in 循环也会遍历原型函数
- 复杂的循环节点模块依赖抛出“类型错误:'继承'的超级构造函数必须有一个原型”
- 在对象中添加方法'的原型通过JavaScript中的循环
- 为什么for.in循环不遍历对象's原型
- 在数组原型中循环
- Javascript -为什么要循环?(原型属性->构造函数属性->函数对象->构造函数属性)
- Javascript原型循环for in数组
- 在 for 循环中将 Bind 添加到原版 Javascript 中的原型对象
- 如果我使用原型创建OOP JS代码,我如何从循环中引用类方法
- 通过原型循环的Javascript