Можете ли вы добавить функцию в угнанный массив 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"
Да... вы только что сделали... но вы создали массив с помощью []
.. если вы используете new Array()
работает нормально...