В Javascript forin не перебирает свойства прототипа?

В MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty), я увидел такой фрагмент:

var buz = {
  fog: 'stack'
};

for (var name in buz) {
  if (buz.hasOwnProperty(name)) {
    console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]);
  }
  else {
    console.log(name); // toString or something else
  }
}

Во фрагменте console.log(name); // toString or something else меня немного сбивает с толку. Я понимаю, что toString является свойством Object.prototype, и к этому свойству может получить доступ buz.toString.

Однако, когда я запускал фрагмент в Chrome, я не видел, чтобы свойство toString печаталось (console.log), хотя в комментариях говорится, что оно должно повторяться с помощью for..in и печататься.

Есть ли у кого-нибудь идеи о том, почему свойства из прототипа не могут быть повторены с помощью «for..in»?


person Hanfei Sun    schedule 11.11.2015    source источник
comment
Object.prototype.toString — это неперечислимое свойство.   -  person Bergi    schedule 11.11.2015


Ответы (2)


for x in obj выполняет итерацию только по перечислимым свойствам объекта (включая свойства прототипа). Данное свойство может быть помечено как перечисляемое или нет. Итак, если for/in пропускает какое-то свойство, то, скорее всего, это свойство не настроено как перечисляемое.

См. рабочую демонстрацию здесь: http://jsfiddle.net/jfriend00/gyc9gnmj/, которая показывает, как только перечисляемые свойства повторяются с for x in obj.

И действительно, вы можете видеть, что метод toString() помечен как enumerable: false с помощью этого кода:

function log(x) {
    document.write(JSON.stringify(x));
}

var buz = {
  fog: 'stack'
};

log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(buz), "toString"));

person jfriend00    schedule 11.11.2015

Просто чтобы пролить больше света в продолжение того, на что jfriend00 уже ответил, свойства данных объекта в JavaScript имеют четыре атрибута, а именно [[configurable]], [[enumerable]], [[writable]] и [[value]], каждый из которых установите для первых трех значение по умолчанию true, а для последнего по умолчанию значение undefined.

Скажем, предположим, что существует потребность, когда вы хотели бы избежать возврата значения свойства в цикле for-in. Вы можете написать как

var car = {};
Object.defineProperty(car, 'name',{
enumerable : false,
value : 'BMW'
});
person Airwind711    schedule 11.11.2015