我正在使用一个名为custommethod
的新方法扩展数组对象,如下所示,并循环遍历数组中的值。但是,循环索引还会打印property
的名称,该名称通过Array.prototype.<method>
进行扩展。
Array.prototype.custommethod = function() {
console.log("Hello from Custom Method");
}
Object.defineProperty(Array.prototype, "anothercustommethod", {
value: function() {
console.log("Hello from Another Custom Method");
}
});
> x = [1,2]
[ 1, 2 ]
> for (i in x) { console.log(i); }
0
1
custommethod
为什么anothercustommethod
不会在此循环中打印出来?
使用Object.defineProperty()
更安全的方式创建Array.prototype
?
我很好奇javascript中的for
循环是如何工作的。它是否在内部使用Object.keys()
?如果是这样,它如何打印custommethod
属于__proto__
属性但不打anothercustommethod
哪个属于__proto__
属性?
答案 0 :(得分:5)
为什么不会在此循环中打印另一个自定义方法?
for in
遍历这些属性,数据描述符enumerable
设置为true。
<强>枚举强> 当且仅当此属性在期间出现时才返回true 枚举相应对象的属性。默认为 假的。
使用defineProperty
时,您还可以传递额外的属性 - 可枚举。
默认情况下,它设置为false。
Array.prototype.custommethod = function() {
console.log("Hello from Custom Method");
}
Object.defineProperty(Array.prototype, "anothercustommethod", {
value: function() {
console.log("Hello from Another Custom Method");
},
enumerable: true
});
const x = [1,2]
for (i in x) { console.log(i); }
使用Object.defineProperty()创建Array.prototype更安全吗?
没有任何关于安全的事情。尝试很少改变原型中的构建
答案 1 :(得分:0)
您可以通过此API检查该属性:
Object.getOwnPropertyDescriptor(Array.prototype,'custommethod');//{value: ƒ, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(Array.prototype,'anothercustommethod');//{value: ƒ, writable: false, enumerable: false, configurable: false}
见?得到的第一个:enumerable:true,第二个得到:enumerable:false,
其他值也不同,因为默认设置在由不同的API
设置时是不同的实际上,想要更安全,可以使用此API:
Object.getOwnPropertyNames
Object.getOwnPropertyNames(Array.prototype).filter(v=>v.endsWith('custommethod'));//["custommethod", "anothercustommethod"]
如果有符号,您仍然需要
Object.getOwnPropertySymbols(Array.prototype);//[Symbol(Symbol.iterator), Symbol(Symbol.unscopables)]
Object.keys的作用与in一样,它们不会遍历其枚举为false的属性;
当您尝试使用其他API遍历属性时,应该考虑这些事情