Пишу, по большей части, про историю, свою жизнь и немного про программирование.

__defineGetter__ в массивах в JavaScript

Метод __defineGetter__ предназначался в ДжаваСкрипте когда-то для того, чтобы назначить свойству объекта геттер, сейчас он объявлен устаревшим, тем не менее, широко поддерживается — у меня на компьютере с ним работают Сафари, Хром, Фаэрфокс и «Опера».

Я тут подумал — можно ли как-то перехватить чтение не просто свойства, а элемента массива, ведь в ДжаваСкрипте широко рекламируется эквивалентность obj[’name’] и obj.name. Провёл эксперимент, оказалось — можно, в перечисленных мною браузерах получается странный эффект:

Array.prototype.__defineGetter__('0', function() {return 1});

var v = [];
alert(v); // выводит пустой массив
alert(v[0]); // выведет единицу

Такой код из разряда «happy debugging, bitch», ломает голову — массив пустой, но нулевой элемент не пуст.

Большие возможности для внедрения, кстати, в приватный код, который спрятан за замыканием — можно ведь и сеттер так же определить и считывать состояния каких-нибудь внутренних массивов. То же и с объектом Object и другими базовыми объектами.

11 комментариев
Азат Разетдинов (razetdinov.ya.ru) 2013

Все операции с массивом танцут от length:

Array.prototype.__defineGetter__(’0’, function() {return 1});
var v = [];
v.length = 1;
alert(v); // выводит единицу

Евгений Степанищев (bolknote.ru) 2013

Комментарий для razetdinov.ya.ru:

Да, какие-то спецэффекты с length я помню. Например, очистку: v.length = 0

Смысл-то в том, что можно пролезть за замыкание или затруднить отладку. :) Например, возвращать значение только с какой-то большой вероятностью, чтобы один раз из сотни оно не возвращалось!

Надо будет на собеседование что-то такое придумать :-D

Арутр 2013

Не ДжаваСкрипт, а Яваскрипт. Не Фаэрфокс, а Фаерфокс. Не «Опера», а Опера.

greli (greli.livejournal.com) 2013

Комментарий для Арутр:

Фа*й*рфокс, в остальном согласен.

greli (greli.livejournal.com) 2013

Комментарий для greli.livejournal.com:

А вот и баг нашёлся: «звёздочки» не выделяют буквы жирным.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для greli.livejournal.com:

А вот и баг нашёлся: «звёздочки» не выделяют буквы жирным.

Какой же это баг? Инструкцию внизу ↓↓↓ внимательно прочтите.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для Арутр:

Не ДжаваСкрипт, а Яваскрипт. Не Фаэрфокс, а Фаерфокс. Не «Опера», а Опера.

Не Яваскрипт, а ДжаваСкрипт. Не Фаерфокс, а Фаэрфокс. Не Опера, а «Опера».

masterspammer (masterspammer.livejournal.com) 2013

(в сторону) Остаётся ещё вспомнить, что FireFox — не лиса, а малая панда...

Евгений Степанищев (bolknote.ru) 2013

Комментарий для masterspammer.livejournal.com:

Где у меня написано, что это лиса?

masterspammer (masterspammer.livejournal.com) 2013

Комментарий для Евгения Степанищева:

Пока ещё не написано :-)

Евгений Степанищев (bolknote.ru) 2013

Комментарий для masterspammer.livejournal.com:

Именно потому, что это не лиса, название и пишется в одно слово: Firefox, а не FireFox :)