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

Перезаписывание конструктора Array не влияет на [], правильно?

Я просто прочитал это: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

У меня создалось впечатление, что перезапись Object или Array имела эффект, если вы решили использовать функции конструктора при создании arrays/ objects, но, согласно этой статье, это также влияет на создание буквального ({} и [])...

Моя логика:

Array = function(){ alert('Hi'); };

[1,2,3,4,5];
([1,2,3,4,5]);
var a = [1,2,3,4,5];

// ...
// ... Nothing is alerted

Итак, я схожу с ума или есть некоторые специфические для реализации особенности, о которых я не знаю?

4b9b3361

Ответ 1

Насколько я знаю, это проблема с спецификацией ECMAScript и была зафиксирована во всех основных браузерах более года назад. Здесь - ссылка, которая связывает вас с наиболее релевантными ссылками;)

Но чтобы ответить на ваш вопрос, да, конструкторы Object и Array также вызываются для литералов. Исправленные браузеры только что сделали эти (и другие) постоянными, поэтому они не могут быть переопределены пользовательскими сценариями.

Ответ 2

Проект EcmaScript 5 стандартизирует это исправление Йозефа. Он определяет поведение конструктора массива в терминах значения массива Array во время создания контекста, как описано в разделе 11.1.4.

Семантика

Произведение ArrayLiteral : [ Elisionopt ] оценивается следующим образом:

  • Пусть массив будет результатом создания нового объекта, как если бы выражение new Array() где Array - стандартный встроенный конструктор с этим именем.

Вместо старого поведения ES 262, позволяющего заменить конструктор Array:

Семантика

Произведение ArrayLiteral : [ Elisionopt ] оценивается следующим образом:

  • Создайте новый массив, как если бы выражение new Array().

Тем не менее, не полагайтесь на [], работая разумно на более старых интерпретаторах.

Ответ 3

Установив Array как функцию, вы не переопределяете конструктор массивов, а вместо этого заменяете функцию.

Чтобы правильно переопределить конструктор, вы должны использовать Array.prototype. defineSetter, чтобы установить метод, вызываемый при построении, и это будет вызываться как на новом Array(), так и при использовании литерала,