Перезапись конструктора Array не влияет на [], верно? - PullRequest
12 голосов
/ 28 июня 2009

Я только что прочитал это: 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

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

Ответы [ 3 ]

14 голосов
/ 28 июня 2009

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

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

5 голосов
/ 21 октября 2009

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

Семантика

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

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

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

Семантика

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

  1. Создать новый массив как бы по выражению new Array().

Тем не менее, не полагайтесь на [], работающий разумно на старых переводчиках.

0 голосов
/ 15 июля 2009

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

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

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