Я думаю, что основное преимущество заключается в возможности контролировать то, что отображается при перечислении свойств объекта, таких как 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
person
Ian
schedule
20.02.2013
for in
безопасными — свойство не будет отображаться при повторении объекта. Может быть, я забыл, что делает перечисление... - person Ian   schedule 20.02.2013