Enumerability是一个属性的三个属性之一:可写,enumerability,和可配置性。 我的问题是:
- 是什么使性能不可枚举在JavaScript的好处? 我知道,我们是通过使它们不可枚举的隐藏属性,但什么是财产隐藏的利益?
- 我们可以访问不可枚举的属性? 如果是,那又是什么使他们不可枚举的好处?
- 是对象的所有预定义的属性设置为不可枚举的? 如Array的情况下
pop
和push
性质是不可枚举的?
Enumerability是一个属性的三个属性之一:可写,enumerability,和可配置性。 我的问题是:
pop
和push
性质是不可枚举的? 我认为主要的好处是能够控制枚举一个对象的属性,如当显示的内容for in
或Object.keys()
MDN与解释得好Object.defineProperty
: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty
因此,一般来说,当人们想添加到一个方法Object
,如在旧的浏览器不支持某些方法的填充工具,他们修改.prototype
。 但是,使财产枚举和打乱了什么是循环/领取钥匙退还( 不使用.hasOwnProperty
......这不是每个人都使用)。
因此,而不是像这样:
Object.prototype.myMethod = function () {
alert("Ahh");
};
你可以使用Object.defineProperty
明确地说,有它不枚举:
Object.defineProperty(Object.prototype, 'myMethod', {
value: function () {
alert("Ahh");
},
enumerable: false
});
通过这种方式,例如,当您使用for (var key in obj)
,“myMethod的”将不再是一个项目枚举,你将不必担心使用.hasOwnProperty
。 与此主要问题是,一些浏览器不支持它,当然: http://kangax.github.com/es5-compat-table/而且不是所有的库/代码中使用它,所以你不能总是依赖外部库/代码做正确的使用和所有的时间。
您可以访问在任何时候你想要一个不可枚举的财产,它只是不会枚举对象的属性时出现 - 这是最主要的一点。
而且我相信,对象的所有“预定义”属性是不可枚举。 到那个,我真的只意味着本机属性,不一定是继承或创建。 所以,你的榜样, pop
和push
不会在列举,但Array.prototype.indexOf
如果它是作为一个古老的浏览器中的填充工具不支持该方法创建将是...这当然可避免通过使用Object.defineProperty
像上面我的例子。 又如length
属性,该属性不枚举过。
下面是一般的例子: http://jsfiddle.net/aHJ3g/
的使用和定义Object.keys
是很重要的:“返回给定对象的自己的枚举的属性的阵列,在相同的顺序,通过提供一个for-in
循环(不同之处在于一个for-in
循环枚举在属性原型链以及)。” -从MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys
在我看来,另一个主要的好处是,它可以防止一个对象的私有财产,防止污染公共命名空间。
假设你已经创建并发布称为功能强大的库Cosmos
。 用户会启动这个节点解释,并通过调用构造函数创建它的一个新的实例:
var Cosmos = require('Cosmos');
var cosmos = new Cosmos('my empire');
现在,用户只需类型的cosmos
,并按下回车看到它所支持的公共API。 你要哪两个用户看的?
{ name: 'my empire',
grow: [Function: grow],
addStar: [Function: addStar],
beautify: [Function: beautify],
implode: [Function: implode],
destroy: [Function: destroy] }
要么
{ _age: 25000,
_size: 35000,
_destroyed: false,
name: 'my empire',
_numStars: 200,
_init: [Function: _init],
grow: [Function: grow],
_grow: [Function: _grow],
addStar: [Function: addStar],
_checkStatus: [Function: _checkStatus],
beautify: [Function: beautify],
implode: [Function: implode],
destroy: [Function: destroy] }
内置对象的继承属性(如PUSH,POP,的toString ...)是不可枚举
var o = {a:1, b:2, c:3} // a,b,c are enumerable properties o.propertyIsEnumerable("toString") // returns false, because it is a inherited property for(p in o) console.log(p); // this loop will print a,b and c but not toString or other inherited properies