我认为主要的好处是能够控制枚举对象属性时显示的内容,例如for in
or Object.keys()
.
MDN 很好地解释了这一点Object.defineProperty
: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/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/ http://kangax.github.com/es5-compat-table/并且并非所有库/代码都使用它,因此您不能总是依赖外部库/代码来正确且始终使用它。
您可以随时访问不可枚举的属性,只是在枚举对象的属性时它不会显示 - 这是要点。
我确实相信对象的所有“预定义”属性都是不可枚举的。我的意思实际上只是指原生属性,不一定是继承或创建的。所以以你的例子来说,pop
and push
will not可以一一列举,但是Array.prototype.indexOf
如果它是在不支持该方法的旧浏览器上创建为polyfill的,那么这当然可以通过使用来避免Object.defineProperty
就像我上面的例子。另一个例子是length
属性,就不一一列举了。
这是一个一般性的例子:http://jsfiddle.net/aHJ3g/ http://jsfiddle.net/aHJ3g/
的使用和定义Object.keys
很重要:“返回给定对象自己的可枚举属性的数组,其顺序与对象提供的顺序相同for-in
循环(区别在于for-in
循环也枚举原型链中的属性)。” - 来自 MDN -https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys