Возможна ли подмена конструкторов у значений, порождаемых простыми конструкциями {} и [] в языке JavaScript?

Как известно, в реальном применении языка JavaScript глобальный объект не бывает единственным: у каждого окна браузера есть свой глобальный объект и своя система глобальных конструкторов, являющихся его полями.


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


Тем не менее, такое разделение имеет свою цену, и зачастую она может представляться излишнею. В частности, простая проверка value instanceof Array не способна сгодиться для проверки того, является ли некоторое переданное значение массивом, если оно было передано из другого контекста, в котором другое значение Array. (Подробнее об этом можно прочесть в статье «Determining with absolute accuracy whether or not ...», например.)


Одним из способов преодоления этого недостатка является создание специальных функций — таких, как метод Array.isArray, появившийся в ECMAScript 5. Этот способ, впрочем, никак не помогает в изменении поведения тех библиотек исходного кода, которые были ранее сочинены без учёта возможной разницы контекстов и без употребления новых функций ECMAScript.


Вторым способом (возможно, даже более очевидным) является замена глобальных объектов одного контекста на глобальные объекты другого контекста. Как-то так:

  • Object = otherContext.Object;

     
  • Array = otherContext.Array;

     
  • и так далее…


К сожалению, приходится видеть, что эквивалентности ({}).constructor === Objectи [].constructor === Array после такой замены оказываются нарушены.


Существует ли способ восстановить их, чтобы простые конструкции {…} и […] продолжили работать, но порождали объекты и массивы заимствованного контекста?
  • Вопрос задан
  • 3338 просмотров
Решения вопроса 1
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Косвенно по теме:
Если пробрасывать данные во фрейм через postMessage, то проблем с x instanceof RegExp/Array не должно быть —
// top
frames.myframe.postMessage([ 'action', [], /x/ ], '*');

// myframe
window.onmessage = function(event){
   event.data[1] instanceof Array // -> true
   event.data[2] instanceof RegExp // -> true
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы