Почему прокладка для watch () и unwatch () при https://gist.github.com/384583 не работает в фантомах? - PullRequest
3 голосов
/ 09 августа 2011

Я делаю некоторые кусочки javascript на стороне сервера, которые, по сути, нуждаются как в доступе к полным DOM веб-сайтов, так и в способности открывать сайты в разных доменах, и, по крайней мере, пока PhantomJS кажется лучшим инструментом для этой работы.

Однако в нем отсутствует метод Object.watch (), который я бы предпочел иметь.Поэтому я пытаюсь использовать прокладку, размещенную в качестве ответа в другом месте Stackoverflow (доступно здесь: https://gist.github.com/384583), чтобы дать мне доступ только к таким методам.

Это не работает.

Это также намного выше моего уровня понимания JavaScript - поэтому мне интересно, может ли кто-нибудь помочь мне понять, что именно он делает, и почему он может не работать?

Спасибо за помощь

Тоби

(Код указан ниже:

// Cross-browser object.watch and object.unwatch

// object.watch
if (!Object.prototype.watch) {
    Object.prototype.watch = function (prop, handler) {
        var oldval = this[prop], newval = oldval,
        getter = function () {
            return newval;
        },
        setter = function (val) {
            oldval = newval;
            return newval = handler.call(this, prop, oldval, val);
        };
        if (delete this[prop]) { // can't watch constants
            if (Object.defineProperty) { // ECMAScript 5
                Object.defineProperty(this, prop, {
                    get: getter,
                    set: setter,
                    enumerable: true,
                    configurable: true
                });
            } else if (Object.prototype.__defineGetter__ &&     Object.prototype.__defineSetter__) { // legacy
                Object.prototype.__defineGetter__.call(this, prop, getter);
                Object.prototype.__defineSetter__.call(this, prop, setter);
            }
        }
    };
}

// object.unwatch
if (!Object.prototype.unwatch) {
    Object.prototype.unwatch = function (prop) {
        var val = this[prop];
        delete this[prop]; // remove accessors
        this[prop] = val;
    };
}

И мой тестовый код:

tO = {
    "v":0,
    "vplus":function(){this.v ++}
};
tO.watch("v", function(prop, oldval, newval) {
    console.log("The property "+prop+" is now "+tO.v+". Newval is "+newval+" and oldval     "+oldval+".");
    if (newval == 5){phantom.exit()};
});
tO.v = 1;
var i = 0
for(i=0; i<10; i++) {
    tO.v = i; 
    console.log(tO.v);
    if(tO.v == 9){
        console.log("got to 9");
    };
};

1 Ответ

1 голос
/ 10 августа 2011

Чтобы ответить на мой собственный вопрос: предоставленная прокладка, кажется, помещает сломанную функцию сеттера на место.В частности, если функция-обработчик не возвращает что-то осмысленное (что вполне может и не быть), для свойства устанавливается значение undefined.Замена

return newval = handler.call(this, prop, oldval, val);

на

var newval = handler.call(this, prop, oldval, val) || val;
return newval;

, казалось, справилась с работой.

В качестве примечания, эта особая прокладка изобретательна, но имеет несколько ограничений:

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

  • Нельзя добавить несколько обработчиков к значению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...