2013-07-27 7 views
92

Я был перенаправлен на MDN for..in page, когда он сказал: «for..in Итерирует над перечислимыми свойствами объекта».Что означает перечислимое значение?

Затем я отправился в Enumerability and ownership of properties page, где он сказал: «Перечислимые свойства - это те, которые могут быть повторены в цикле for..in».

Словарь определяет перечислимый как счетный, но я не могу представить, что это значит. Могу ли я получить пример того, что можно перечислить?

+0

Вы понимаете, что означает 'for-in'? –

+0

Из ответов, которые я получил, для .. .. позволяет все перечисленные свойства объекта быть доступными для использования с оператором for. – Patrick

+5

Простейшим значением является то, будет ли свойство создаваться в цикле 'for in' или нет (для те, кто не хочет знать подробности или просто не волнует;)) –

ответ

90

Перечислимое свойство - это такое, которое может быть включено и посещено во время циклов for..in (или аналогичная итерация свойств, например Object.keys()).

Если свойство не идентифицировано как перечислимое, цикл игнорирует, что он находится внутри объекта.

var obj = { key: 'val' }; 

console.log('toString' in obj); // true 
console.log(typeof obj.toString); // "function" 

for (var key in obj) 
    console.log(key); // "key" 

Свойство определяется как перечислимы или не по своей [[Enumerable]] attribute. Вы можете рассматривать это как часть property's descriptor:

var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar'); 

console.log(descriptor.enumerable); // true 
console.log(descriptor.value);  // 1 

console.log(descriptor); 
// { value: 1, writable: true, enumerable: true, configurable: true } 

for..in петля затем итерацию имена свойств объекта.

var foo = { bar: 1, baz: 2}; 

for (var prop in foo) 
    console.log(prop); // outputs 'bar' and 'baz' 

Но только оценивает его заявление - console.log(prop); в данном случае - для тех свойств, [[Enumerable]] атрибут true.

Это условие на месте, потому что объекты have many more properties, особенно from inheritance:

console.log(Object.getOwnPropertyNames(Object.prototype)); 
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */] 

Каждое из этих свойств еще exists on the object:

console.log('constructor' in foo); // true 
console.log('toString' in foo); // true 
// etc. 

Но они пропускаются (или "не подсчитывали ") в цикле for..in, потому что они не перечислимы.

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor'); 

console.log(descriptor.enumerable); // false 
+0

Таким образом, свойство конструктора не перечислимо, потому что оно не отображается в цикле for..in. Хотя имена свойств, таких как bar или baz, перечисляются, потому что вы могли console.log каждый из объекта? – Patrick

34

Если вы создаете объект с помощью myObj = {foo: 'bar'} или что-то около того, все свойства перечислимы. Так что проще задать вопрос, что не перечислимо? Некоторые объекты имеют некоторые неперечислимые свойства, например, если вы вызываете Object.getOwnPropertyNames([]) (который возвращает массив всех свойств, перечисляемых или нет, в []), он возвращает ['length'], который включает в себя неперечислимое свойство массива, длина.

Вы можете сделать свои собственные несчетных свойства по телефону Object.defineProperty:

var person = { age: 18 }; 
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false }); 

person.name; // 'Joshua' 
for (prop in person) { 
    console.log(prop); 
}; // 'age' 

Этот пример заимствует из Non-enumerable properties in JavaScript, но показывает объект быть перечислены более. Свойства могут быть или не быть перезаписываемыми, настраиваемыми или перечислимыми. Джон Ресиг обсуждает это в области ECMAScript 5 Objects and Properties.

И, есть вопрос переполнения стека о why you'd ever want to make properties non-enumerable.

+0

Hm, как upvotes, так и downvotes. Конечно, если есть что-нибудь об этом ответе, которое стоит закваски, пожалуйста, добавьте комментарий здесь. – carpeliam

+0

Другой ответ написал следующее: var o = {}; o ['foo'] = 0; // enumerable, normal Object.defineProperty (o, 'bar', {value: 1}); // nonenumerable, weird Почему явным образом добавляю перечислимое: false? – Patrick

+5

@Patrick, я включил его здесь частично, так что из примера видно, что это вариант, но, в зависимости от вашей аудитории, быть явным может быть твердое решение, так что всем понятно, кто читает ваш код. – carpeliam

9

Если у вас возникли трудности с визуализацией «что значит быть перечислимым?» почему бы не спросить себя, что значит быть не подлежит сомнению?

Я думаю о нем немного, как этого, nonenumerable свойство существует но частично скрытые; что означает, что не подлежит сомнению является странным. Теперь вы можете представить себе перечислимое как то, что осталось - более естественное свойство, с которым мы привыкли сталкиваться, так как мы обнаружили Объекты. Рассмотрим

var o = {}; 
o['foo'] = 0;        // enumerable, normal 
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird 

Теперь в for..in, представьте себе это как псевдокоде

for property in o: 
    if not property enumerable continue // skip non-enumerable, "bar" 
    else do /* whatever */    // act upon enumerable, "foo" 

, где тело цикла введенному в JavaScript находится в месте /* whatever */

18

Это намного более скучно, чем что-то, что должно быть визуализировано.

Существует буквально атрибут для всех свойств, называемых «перечислимыми». Когда он установлен в false, метод for..in пропустит это свойство, притворись, что он не существует.

Существует много свойств объектов, для которых «перечислимый» установлен как false, например «valueOf» и «hasOwnProperty», потому что предполагается, что вы не хотите, чтобы движок JavaScript повторял их.

Вы можете создавать свои собственные несчетных свойства с помощью метода Object.defineProperty:

var car = { 
    make: 'Honda', 
    model: 'Civic', 
    year: '2008', 
    condition: 'bad', 
    mileage: 36000 
    }; 

    Object.defineProperty(car, 'mySecretAboutTheCar', { 
    value: 'cat pee in back seat', 
    enumerable: false 
    }); 

Теперь, тот факт, что есть даже тайна о машине скрыт. Конечно, они все еще могут получить доступ к свойству напрямую и получить ответ:

console.log(car.mySecretAboutTheCar); // prints 'cat pee in back seat' 

Но они должны знать, что свойство существует первое, потому что если они пытаются получить к нему доступ через for..in или Object.keys он будет оставаться полностью секретно:

console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage'] 

Они должны были просто назвать это «forInAble».

+2

Приобретено для этой последней строки - я думаю, что если бы это действительно было вызвано forInAble, никто бы не спросил об этом вообще. Что вызывает мой вопрос: зачем вам (или почему вам нужно) установить свойство, чтобы оно не было перечислимым? Свойство length массива используется довольно часто в качестве примера неперечислимого свойства, но почему вы не можете просто указать его на перечисление (а не на ограничение JavaScript, я имею в виду, почему он был настроен так, чтобы он не был перечислим в JavaScript в первое место)? – Chris

+0

Чтобы прояснить мой вопрос, почему было принято решение о том, что следующее не вариант: Марка: Honda Модель: Civic секрет: Cat мочиться ** Длина: 12 ** – Chris

+0

Хммм ... Я, возможно, нашли ответ на мой собственный вопрос. Из поиска в Google: «Что вы понимаете под перечисляемыми типами данных?» Перечисленные данные имеют конечный набор значений. Перечислимый тип данных состоит из значений, которые вы разрешаете для этого типа, или перечисляемых значений. Для перечисляемых типов с целыми числами каждое перечислимое значение состоит из имени и базового числового значения. Поэтому, если я правильно понимаю, поскольку существует бесконечное количество возможных длин, вам придется назначать бесконечное число имен, одно имя на каждую длину. Это верно? – Chris

0

методы не перечислены; или, скорее, встроенные методы не .. tho после поиска на то, что перечислимый означает java-скрипт; он просто ссылается на атрибут свойства .. все созданные объекты в ecma3 перечислены, и ecma5 u теперь может определить его ... вот и все ..: D lol взял меня немного, чтобы найти ответ; но я верю, что его рассказывали в книге Дэвида Фланагана .. так что я думаю, что это означает «скрытый» или «скрытый» в том, что методы не показаны в цикле for in и, таким образом, «скрыты»

2

Я буду написать однострочное определение ENUMERABLE

Enumerable: Указывает, может ли свойство быть возвращено в цикле for/in.

var obj = {}; 
Object.defineProperties(data, { 
    set1: {enumerable: true}, 
    set2: {enumerable: false}, 
}); 
Object.keys(obj); // ["set1"] 
Object.getOwnPropertyNames(obj); // ["set1", "set2"] 
Смежные вопросы