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

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

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


person James    schedule 27.06.2009    source источник


Ответы (3)


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

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

person Josef Pfleger    schedule 27.06.2009
comment
Идеальный! Спасибо за ссылку :) - person James; 28.06.2009

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

Семантика

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

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

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

Семантика

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

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

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

person Mike Samuel    schedule 21.10.2009

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

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

person Sean Kinsey    schedule 15.07.2009
comment
Неверно согласно разделу 11.4.1 спецификации EcmaScript 262. - person Mike Samuel; 21.10.2009