Що означає численні?


151

Мене скерували на сторінку MDN for..in, коли вона сказала: "for..in Взаємодіє з перелічуваними властивостями об'єкта".

Потім я перейшов на сторінку « Перелічуваність та право власності на властивості», де написано «Перелічені властивості - це ті, які можна повторити циклом for..in».

Словник визначає численні як лічильні, але я не можу реально уявити, що це означає. Чи можу я отримати приклад того, що щось перелічується?


Ви розумієте, що for-inробить?

З відповідей я отримав, що для..in дозволяє всі перелічені властивості об'єкта бути доступними для використання з оператором for
Патрік

6
Найпростіший сенс: чи буде майно вироблятися for inциклом чи ні (для тих, хто не хоче знати деталі або просто не цікавить;))
Tomasz Racia

Відповіді:


158

Численні властивості - це ті, які можна включати і відвідувати під час 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]]атрибутом . Ви можете переглянути це як дескриптор властивості :

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.

Ця умова діє, тому що об'єкти мають набагато більше властивостей , особливо внаслідок спадкування :

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

Кожне з цих властивостей все ще існує на об'єкті :

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

Таким чином, властивість конструктора не перелічується, оскільки не відображається у циклі for..in. Хоча назви таких властивостей, як bar або baz, перелічені через те, що ви змогли консолірувати.log кожен з об'єкта?
Патрік

5
Це не зовсім коректно: But, they are skipped (or not counted) by the for..in loop because they are not enumerable. Властивості на Object.prototypeнасправді ігноруються через те, що вони далі в ланцюзі прототипу, а не тому, що вони не перелічені. Ні getOwnPropertyNames()і не keys()показуйте властивості, які не є власними об'єктами. Як бічне зауваження, правда, що багато вбудованих властивостей не перелічені, і тому вони не відображатимуться keys(), але вам доведеться написати додатковий код, якщо ви хочете пройти ланцюг прототипу.
Магнус

Буквально, перелічувані засоби підлічуються
Крістіан Матвій

49

Якщо ви створюєте об'єкт через myObj = {foo: 'bar'}або щось із цього, всі властивості перелічені. Тож простішим питанням є те, що не перелічено? Окремі об’єкти мають деякі неперелічені властивості, наприклад, якщо ви викликаєте Object.getOwnPropertyNames([])(який повертає масив усіх властивостей, перелічений чи ні, на []), він повернеться ['length'], що включає нечисельну властивість масиву, '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'

Цей приклад значною мірою запозичує неперелічені властивості JavaScript , але показує об'єкт, який перераховується. Властивості можуть бути або не підлягати запису, конфігуруватися чи перелічуватися. Джон Резіг обговорює це в межах об'єктів та властивостей ECMAScript 5 .

І є запитання щодо переповнення стека щодо того, чому ви хочете коли-небудь зробити властивості незліченними .


Hm, як upvotes, так і downvotes. Звичайно, якщо є щось про цю відповідь, яку варто подбати, будь ласка, додайте тут коментар.
carpeliam

1
Ще одна відповідь написала це: var o = {}; o ['foo'] = 0; // перелічувальний, нормальний Object.defineProperty (o, 'bar', {значення: 1}); // незчисленний, дивний Чому явно додають нумерацію: false?
Патрік

5
@Patrick, я включив його сюди частково, щоб на прикладі було зрозуміло, що це варіант, але залежно від вашої аудиторії бути явним може бути надійним рішенням просто так, щоб зрозуміти всім, хто читає ваш код.
карпеліам

@carpeliam Дякую за це коротке і дуже чітке пояснення, я не зміг отримати прийняту відповідь, поки не пережив вашу: D
sandeepKumar

37

Це набагато нудніше, ніж щось, що слід візуалізувати.

У всіх властивостях буквально є атрибут під назвою "перелічувальний". Якщо встановлено значення false, for..inметод пропустить це властивість, зробіть вигляд, що він не існує.

Існує маса властивостей об’єктів, у яких "кількість" встановлена ​​на помилку, як "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".


5
Запропонований за цей останній рядок - я думаю, якби насправді його називали InAble, ніхто б про це взагалі не питав. Який піднімає моє запитання - чому б ви (або чому ви повинні) встановити властивість не Рахункова? Властивість довжини масиву використовується досить часто як приклад властивості, яка не перелічується, але чому ви не могли просто встановити її для перерахування (не обмеження JavaScript, я маю на увазі, чому воно було встановлено таким, що не перераховується в JavaScript в перше місце)?
Кріс

Щоб уточнити моє запитання, чому було вирішено, що наступне не є варіантом: виготовити: модель Honda: Громадянська таємниця: Довжина
Кріс

Гммм ... я, можливо, знайшов відповідь на власне запитання. З пошуку в Google "Що ви розумієте під переліченими типами даних?" Перелічені дані мають кінцевий набір значень. Перелічений тип даних складається із значень, які ви дозволяєте для цього типу, або перелічених значень. Для перелічених типів на основі цілого числа кожне перелічене значення складається з імені та нижнього числового значення. Отже, якщо я правильно розумію, оскільки існує нескінченна кількість можливих довжин, вам доведеться призначити нескінченну кількість імен, одне ім'я до кожної довжини. Це правильно?
Кріс

Що ж, вирішити своє перше запитання, встановити нечисленний властивість на об’єкт - це трохи хакітно, оскільки єдиним способом, яким ви зможете дізнатися, що було на цьому об’єкті, було б дивитись на код і як на кодову базу розвивається, його можна було б поховати. Тому, як правило, ви не хотіли б ним користуватися. Щодо ".length", який дає кількість символів у рядку або елементів у масиві - це лише те, що, як ми вважаємо, ми не хотіли б включати, якби використовували "для ... в". Не можу відповісти, чому боги Дж. Зробили це таким чином обов'язково. Вони мають причини ( ах ) думки поза нашим розумінням.
Габріель Кункель

... і я не думаю, що я міг би відповісти на ваше друге запитання про перелічені типи даних, хоча це схоже на те, що я міг би жувати досить довго, якби мав час. :-)
Габріель Кункель

9

Якщо у вас виникають труднощі з уявленням, "що означає бути численним?" чому б не запитати себе, що означає бути незліченною ?

Я думаю про це дещо так, незліченна властивість існує, але частково прихована ; це означає, що нечисленні є дивні. Тепер ви можете уявити незліченну кількість того, що залишилося - тим більше природних властивостей, з якими ми звикли стикатися з тих пір, як ми виявили об’єкти . Розглянемо

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

Тепер у a for..in, уявіть це як псевдокод

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

де тіло циклу введеного в JavaScript в місці/* whatever */


8

Я напишу визначення одного рядка ENUMERABLE

Enumerable: Вказує, чи можна повернути властивість у циклі for / in.

var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]

0

методи не перелічені; а точніше, вбудовані методи не є .. після пошуку того, що перераховує численні сценарії Java; він просто посилається на атрибут властивості .. всі створені об'єкти в ecma3 перелічені, і ecma5 u тепер може це визначити .... ось це ..: D lol трохи взяв мене, щоб знайти відповідь; але я вважаю, що про це говорилося в книзі Девіда Фланагана .. тому я гадаю, що це означає «приховано», або не «приховано» в тому, що методи не відображаються в циклі «for in» і, таким чином, «приховуються»


0

Подумайте про тип даних enum, просто про структуру об'єктів, які відповідають різним числам. Декларувати щось як перелічувальне - це заявити, що воно відповідає певній кількості, що дозволяє йому відводити місце в словнику, що представляє лічильні компоненти об'єкта. Простіше кажучи, зробити об'єкт численним - це те саме, що сказати компілятору: "Ей, ця властивість рахується. Я хочу це побачити, коли я перевіряю дані про цей об'єкт".


0

Вбудовані методи, які успадковують об'єкти, не перелічуються, але властивості, які ваш код додає до об'єктів, перелічуються, якщо прямо не зазначено

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.