Можете ли вы добавить функцию в угнанный массив JavaScript?

Этот вопрос связан с тем, каковы наилучшие практики, которым нужно следовать при объявлении массива в Javascript?


Допустим, клиент, назовем их "DB Cooper", имеет первое требование, чтобы следующий код должен выполняться перед любым другим кодом JavaScript:

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

Кроме того, Купер требует, чтобы пользовательские функции были добавлены к встроенным Array объект (не угнанный). Например, если Array был угнан, это будет сделано с:

Array.prototype.coolCustomFunction = function(){
    alert('I have ' + this.length + ' elements!  Cool!');
};

Который мог бы позволить:

var myArray = [];
myArray.coolCustomFunction();

Однако это не совместимо с первым требованием. Таким образом, как вы можете наилучшим образом удовлетворить оба требования DB Cooper?

Примечание: DB даже написал тестовую скрипку, чтобы убедиться, что решения соответствуют его требованиям... что за парень!


Обновление: для тех из вас, кто любит вызовы: попробуйте найти решение для этой проблемы, которое можно использовать без кражи. Например, вот еще более угнанный тестовый пример (спасибо за переформатирование этого Bergi), который захватывает Array, Object, Array.prototype.constructor и Object.prototype.constructor. До сих пор, похоже, что это может быть решение для конкретного браузера (см . Комментарий Берги к его ответу, и дайте нам знать, если вы найдете способ угнать его в FF), но на данный момент неясно, есть ли кросс-браузерное решение для этого.

3 ответа

Решение

Независимо от вашего Array функция / конструктор, буквальный синтаксис для массивов всегда будет генерировать "реальные" массивы с их [[prototype]], установленным в объект-прототип нативного массива (когда-то это была уязвимость безопасности). Таким образом, вы всегда можете получить доступ к этому с помощью

Object.getPrototypeOf([])

даже если Array или же [].constructor угнаны. (Конечно, не будет работать, когда Object угнан, тогда это становится действительно сложно)

( Сбил БД!)


Если вы хотите использовать обходной путь, в FF всегда будет работать следующая строка (и ее нельзя угнать):

[].__proto__.coolCustomFunction = coolCustomFunction;

Поскольку Array не обязательно равен [].constructorВы могли бы использовать [].constructor ссылаться на оригинальную функцию массива, так как это аппаратно и Array = function(){} не изменит это.

Array = function () { alert("foo")};

// this will always point to the original Array
[].constructor.prototype.foo = "bar";

var myArray = [0, 1];
alert(myArray.foo) // alerts "bar"

http://jsfiddle.net/yXPJ8/5/

Да... вы только что сделали... но вы создали массив с помощью [].. если вы используете new Array() работает нормально...

Смотрите пример здесь

Другие вопросы по тегам