Подтвердить что ты не робот

Мониторинг всех свойств объекта JavaScript (магические геттеры и сеттеры)

Как эмулировать PHP-стиль __get() и __set() magic getter/seters в JavaScript? Многие говорят, что в настоящее время это невозможно. Я почти уверен, что это возможно, потому что проекты вроде nowjs (http://nowjs.com) делают что-то вроде этого.

Я знаю, что вы можете использовать get и set, но это не работает, когда вы не знаете, каким будет имя свойства. Например, что, если вы хотите, чтобы обработчик события выполнялся при создании нового свойства?

Пример того, что я хочу сделать:

var obj = {};
notify(obj, function(key, value) {
   //key is now the name of the property being set.
   //value is the value of the property about to be set
   console.log("setting " + key + " to " + value);
});
obj.foo = 2; //prints "setting foo to 2"
obj.bar = {a: 2}; //prints "setting bar to [Object]"
//Notice that notify() worked even though 'foo' and 'bar' weren't even defined yet!

(Вопрос аналогичен следующим вопросам:

)

EDIT: Похоже, эта функция называется "динамическими прокси" и должна появляться в стандарте ECMAScript "Гармония" (возможно, ES6). Вы можете прочитать здесь здесь. Новый объект "Прокси" вводится с помощью нескольких методов (I.e. Create() и createFunction()).

Можно сделать следующее:

//Constructing an object proxy (proto is optional)
var proxy = Proxy.create(handler, proto);
proxy.foo = 2; //Triggers 'set' function in the handler (read about it)

Внизу: он не работает в большинстве браузеров, но реализация доступна для Node.js: node-proxy.

4b9b3361

Ответ 1

Просматривая исходный код nowjs, я считаю, что они это делают, постоянно контролируя объект now и изменяя изменения между клиентом и сервером всякий раз, когда они обнаруживаются. Я признаю, что я еще не полностью проверил их код.

В браузере это будет сделано с некоторыми забавными хаками setInterval.

EDIT: да, это действительно то, что они делают: строка 368 клиента now.js. Они делают еще несколько трюков, так что, как только обнаружено новое свойство, будущий доступ к нему пойман геттерами и сеттерами, но эти изменения производятся только каждые 1000 мс в setTimeout.

Еще одно доказательство того, что это невозможно в текущем JavaScript, заключается в том, что предложение прокси для ECMAScript Harmony явно предназначено для включения таких сценариев, что очень важно, что они могут в настоящее время. Недавние браузеры Mozilla имеют прототип прокси-реализации, если возможно, этого достаточно. И, видимо, V8 работает над добавлением поддержки, чего может быть достаточно в зависимости от того, какая версия V8 Node используется в эти дни.

EDIT2: о, круто, на стороне сервера, видимо, теперь использует пользовательские прокси! Скорее всего, они достаточно зрелы в Node для вашего использования. Посмотрите, что они делают в https://github.com/Flotype/now/blob/master/lib/proxy.js. Или просто сделайте var Proxy = require("nodejs-proxy") и надейтесь, что они последуют за спецификацией, чтобы вы могли использовать документацию из MDC и в других местах.

Ответ 2

В Firefox вы можете использовать Object.watch. Если вы посмотрите на эту тему, Object.watch() для всех браузеров?, там есть пример использования чего-то подобного во всех браузерах.

Ooops, я просто понял, что вы хотите посмотреть все свойства, а не конкретное свойство... Решение выше - посмотреть конкретное свойство.

Ответ 3

Возможно, этот пост поможет...? Это, однако, только для определенных свойств и браузеров, основанных на Gecko... Если вам нужна поддержка других браузеров, то это глючит, но вы можете посмотреть на onpropertychange. Здесь Страница MSDN. Надеюсь, что немного помогает...