Каковы преимущества того, что свойства не перечисляются?

Перечислимость является одним из трех атрибутов свойства: возможность записи, перечислимость и конфигурируемость. Мои вопросы:

В чем преимущество того, что свойства не перечисляются в JavaScript? Я знаю, что мы скрываем собственность, делая ее не перечисляемой, но в чем выгода сокрытия собственности?Можем ли мы получить доступ к не перечисляемым свойствам? Если да, то какая польза от того, что они не перечисляются?Все предопределенные свойства объектов установлены как не перечисляемые? Такие, как в случае с Array'spop а такжеpush свойства не перечисляются?
 Ian20 февр. 2013 г., 17:12
Я думаю, что главное преимущество состоит в том, чтобы сделатьfor in петли безопасны - собственность выигралаt появляется при переборе объекта. Может я'я забыл, что делает перечислимость ...

Ответы на вопрос(3)

Сделав свойство не перечисляемым, вы все равно сможете получить к нему доступ. Но когда вы применяете цикл for для объекта, не перечисляемое свойствоне повторяться.Смотрите первый пункт

Унаследованные свойства встроенных объектов (такие как 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
 Scott Sauyet20 февр. 2013 г., 18:02
Я считаю, что третий пункт неверен. Унаследованные свойства, безусловно, так же легко перечисляются, как и любые другие ...var x = {a: 1}; var y = Object.create(x); y.b = 2; for (name in y) {console.log(name, y[name]);}  доходностьb 2 а также .a 1

На мой взгляд, еще одним важным преимуществом является то, что он предотвращает загрязнение общедоступного пространства имен частными свойствами объекта.

Скажем, вы создали и опубликовали мощную библиотеку под названиемCosmos, Пользователь запускает интерпретатор Node и создает его новый экземпляр, вызывая конструктор:

var Cosmos = require('Cosmos');
var cosmos = new Cosmos('my empire');

Теперь пользователь просто печатаетcosmos и нажимает enter, чтобы увидеть, какой публичный 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] }
 Matthew26 янв. 2016 г., 13:57
не перечислимые свойства все еще общедоступны и все еще загрязняют пространство имен. Если вы хотите частную собственность, вам нужно закрытие.
 Andrew Willems08 мар. 2016 г., 00:44
Я проголосовал как за ответ, так и за критический комментарий. Комментарий'Критика кажется мне обоснованной, поэтому, возможно, ответчикс использованием "общественности» а также "частный" не может быть оптимальным. Тем не менее, я думаю, что смысл ответа по-прежнему полезен (по крайней мере, для меня), потому что он показывает, как перечисляемость может помочь пользователю библиотеки легче увидеть, что автор библиотеки намеревался использовать для пользователя библиотеки (например, используйтеgrow и не_growдаже если оба технически публичны).
Решение Вопроса

Я думаю, что главное преимущество заключается в возможности контролировать то, что появляется при перечислении объекта »свойства, такие какfor in или же .Object.keys()

MDN хорошо объясняет это:Object.definePropertyhttps://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty

Так обычно, когда люди хотят добавить методObjectтакие как polyfill для некоторых методов, не поддерживаемых старыми браузерами, они изменяют.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/ и что не все библиотеки / коды используют его, так что вы можетеt всегда полагаться на внешние библиотеки / код для правильного и постоянного использования.

Вы можете получить доступ к не перечисляемому свойству в любое время, оно просто выигралоне появляется при перечислении объектасвойства - этоСуть дела.

И я верю, что все "предопределенный» свойства объектов не перечисляются. Под этим я действительно имею в виду только нативные свойства, которые не обязательно наследуются или создаются. Итак, с вашим примером,pop а такжеpush будутне быть перечисленным, ноArray.prototype.indexOf будет, если он будет создан как polyfill на старом браузере, который нене поддерживает этот метод ... которого, конечно, можно избежать с помощью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

Ваш ответ на вопрос