Получить ВСЕ имена свойств - PullRequest
2 голосов
/ 17 января 2020

В следующем коде я получаю true, то есть свойство someMagic является собственным свойством obj, по крайней мере, в Chrome и Firefox.

Но когда я пытаюсь получить полный список свойств через getOwnPropertyNames возвращенный массив НЕ содержит его в обоих браузерах. В chrome я получаю единственное свойство constructor, а в FF результат - пустой массив. Почему?

Можно ли получить все имена?

var obj = Object.getPrototypeOf(Object.getPrototypeOf(window))
console.log(obj.hasOwnProperty('someMagic'))
console.log(Object.getOwnPropertyNames(obj))
<div id="someMagic"></div>

Ответы [ 2 ]

2 голосов
/ 17 января 2020

Как говорит @Bergi в своем комментарии, объект window обернут чем-то, что называется WindowProxy . Точно так, как он говорит: exoti c, proxy-like (и своеобразный и волшебный c :-). Еще немного подробностей из спецификации:

WindowProxy - это объект exoti c, который оборачивает обычный объект Window, направляя большинство операций через обернутый объект. Каждый контекст просмотра имеет связанный объект WindowProxy. При навигации по контексту просмотра объект Window, обернутый связанным с контекстом просмотра объектом WindowProxy, изменяется.

Объект WindowProxy exoti c должен использовать обычные внутренние методы, за исключением случаев, когда это явно указано иначе, ниже.

Последняя часть об использовании обычных внутренних методов «кроме случаев, где явно указано» является ключевой.

В стандарте EcmaScript 262 указано, что hasOwnProperty использует GetOwnProperty. И getOwnPropertyNames использует OwnPropertyKeys. И обратите внимание, что оба они переопределяются в WindowProxy:

7.4.5 [[GetOwnProperty]] (P)

7.4.10 [[OwnPropertyKeys]] ()

Итак, два свойства, которые вы используете выше, оба используют переопределенные, необычные методы, а не "обычные внутренние методы". И, следовательно, они дают необычные результаты. Под 7.4.5 GetOwnProperty есть даже предупреждение, которое предупреждает о «преднамеренном нарушении» спецификаций:

Это преднамеренное нарушение инвариантов спецификации JavaScript основных внутренних методов для поддерживать совместимость с существующим веб-контентом. См. Tc39 / ecma262, выпуск № 672, для получения дополнительной информации. [JAVASCRIPT]

Этот Ответ StackOverflow дает немного больше истории того, как это странное поведение стало частью HTML5 стандарта.

0 голосов
/ 17 января 2020

Вы можете использовать for in, чтобы сделать это

ПРИМЕР:

const obj =  {
  property: 'test',
  property2: 'test2'
}

for(property in obj)
  console.log('PROPERTY', property)

РЕЗУЛЬТАТ КОНСОЛЬ

const obj =  {
  property: 'test',
  property2: 'test2'
}

for(property in obj)
  console.log(property)

> "property"
> "property2"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...