Перезаписывание конструктора 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
Итак, я схожу с ума или есть некоторые специфические для реализации особенности, о которых я не знаю?
Ответы
Ответ 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(), так и при использовании литерала,