赋予 Array.prototype 的 JS 函数被视为数组属性
Array.prototype.testi = function() {console.log('hep');}
var b = new Array();
b.push(1, 5, 'b', 'c');
for (var i in b) {
console.log(b[i]);
}
这将登录(在 Chrome 中)
1
2
b
c
function () {console.log('hep');}
或 http://jsfiddle.net/marqs/6VVka/1 中的实时示例/
我的问题是,为什么该函数显示在清单中,即使它是给数组原型的?
这对于扩展未使用的浏览器功能有影响(例如,如果使用数组等,IE 扩展的 Array.filter 将表现不同)。
编辑: 需要澄清的是,我无法访问执行 for-in 循环的代码,因为它是外部库。因此,问题的提出更多地是关于“为什么会这样”,而不是如何解决这个问题。
Array.prototype.testi = function() {console.log('hep');}
var b = new Array();
b.push(1, 5, 'b', 'c');
for (var i in b) {
console.log(b[i]);
}
This will log (in chrome)
1
2
b
c
function () {console.log('hep');}
Or live example in http://jsfiddle.net/marqs/6VVka/1/
My question is, why is the function shown in the listing, even though it's given to the array prototype?
This has implications for extending browser functionalities that aren't used (for ex. IE extended Array.filter will behave differently if array in is used etc).
Edit:
to clarify, I have no access to the code that does the for-in loop, as it's an external library. Thus the formulation of the question, more about "why is this so" than how to fix this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
JavaScript 对象是属性的集合。在这些属性内部,有一些描述属性的属性。您在这里看到的主要属性是 [[Enumerable]] 属性,它是一种扩展至 JavaScript 中大多数默认对象(例如数组和对象)的元属性。 ECMAScript 5 定义了一种添加非 [[Enumerable]] 对象的方法,但浏览器可能并未广泛支持。
防止枚举不需要的对象属性的一种方法是检查对象属性是否具有名为
[[GetOwnProperty]]
的内部属性方法。这确保了该属性是直接在对象上调用的,而不是沿着原型链的某个地方继承的。来源: http://javascriptweblog.wordpress.com/ 2011/01/04/exploring-javascript-for-in-loops/
JavaScript Objects are a collection of properties. Inside these properties, there are properties that describe the properties. The main one you are looking at here is the [[Enumerable]] property, which is a meta-property extended to most of the default objects in JavaScript, such as Array and Object. ECMAScript 5 defines a method for adding non-[[Enumerable]] objects, but that may not be widely supported in browsers.
One way to prevent enumerating over object properties you don't want is to check if the object property has an internal property method called
[[GetOwnProperty]]
. This ensures the property was directly invoked on the object and NOT inherited somewhere along the prototype chain.Source: http://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/
for-in 循环将循环遍历对象的所有继承属性及其自身属性。 Ecmascript 5 中有一种方法可以隐藏枚举属性,请参阅 Ecmascript 5 对象和属性,但这在 IE 中不起作用。迭代数组的推荐方法是使用普通的 for 循环:
这也比 for-in 循环具有更好的性能,因为它避免了通过原型链查找对象的属性。
len
变量用于缓存数组的长度,以避免在循环的每次迭代中查找它。如果您想要更灵活,您可以:这会反向迭代数组,并避免额外的 len 变量。
The for-in loop will loop though all inherited properties of an object as well as its own properties. There is a way in Ecmascript 5 to hide your properties from enumeration, see Ecmascript 5 Objects and Properties, but this doesn't work in IE. The recommended way to iterate an array is to use the normal for loop:
This will have much better performance than the for-in loop as well because it avoids looking for properties on the object through the prototype chain. The
len
variable is used to cache the length of the array to avoid looking it up on each iteration of the loop. If you want to be slick, you can:This iterates the array in reverse, and avoids the additional
len
variable.您在对象原型上添加的任何内容都将出现在该对象的所有实例中。这就是我们在 javascript 中扩展对象的方法。
请参考:http://phrogz.net/js/classes/ExtendingJavaScriptObjectsAndClasses.html
Any thing you add on an object's prototype, will appear in all of the instances of that object. This is how we can extend objects in javascript.
Please refer to: http://phrogz.net/js/classes/ExtendingJavaScriptObjectsAndClasses.html
显然道格拉斯·克罗克福德(Douglas Crockford)写过同样的问题。
http://yuiblog.com/blog/2006/09/26/为了阴谋/
Apparently Douglas Crockford has written about the same issue.
http://yuiblog.com/blog/2006/09/26/for-in-intrigue/