Подтвердить что ты не робот

Может ли кто-нибудь объяснить этот метод Javascript?

Исходный источник: http://twitter.com/tobeytailor/status/8998006366

(x=[].reverse)() === window // true

Я заметил, что это поведение влияет на все родные типы. Что именно происходит здесь?

4b9b3361

Ответ 1

Это связано с тем, что привязка this работает в JavaScript.

[].reverse

- это метод reverse в пустом списке. Если вы его вызываете, выполните одно из следующих действий:

[].reverse();
[]['reverse']();
([].reverse)();

то он выполняется с this, привязанным к экземпляру списка []. Но если вы отделите его:

x= [].reverse;
x();

он выполняется без привязки this, поэтому this в функции указывает на глобальный объект (window) в одном из самых худших, наиболее ошибочных ошибок дизайна в JavaScript.

(x=[].reverse)()

Также делает отрыв. Оператор присваивания возвращает тот же объект функции, который был передан, поэтому он выглядит так, как будто ничего не делает, но имеет побочный эффект нарушения ограниченного частного случая, который заставляет JavaScript связывать this.

Итак, вы говорите:

Array.prototype.reverse.call(window)

reverse, как и многие другие методы Array.prototype, определяется ECMAScript для работы с любым нативным подобным последовательности объекту. Он меняет позиции с помощью клавиш с числовой строкой (до object.length) и возвращает объект. Таким образом, он вернет объект, который был передан для любого типа с атрибутом length.

window имеет свойство length, которое соответствует window.frames.length, поэтому вызов этого метода с this, указывающим на window, будет работать и возвращает window. Теоретически он все равно может потерпеть неудачу, потому что:

  • window разрешено быть "объектом-хозяином", а не "родным объектом"; в этом случае гарантии о том, что вы можете передать другим методам прототипов, не обязательно применяются; и
  • Если в окне действительно есть фреймы/фреймы, он попытается отменить свой порядок, который не будет работать, потому что коллекция фреймов доступна только для чтения.

Однако в текущих браузерах первый случай работает, и последний не работает без ошибок, поэтому вы по-прежнему получаете поведение ===window, а не исключение.