3

我正在做一些服务器端的 javascript 零碎工作,它们基本上需要访问网站的完整 DOM 和跨域打开站点的能力,至少到目前为止,PhantomJS 似乎是完成这项工作的最佳工具。

但是,它缺少我希望拥有的 Object.watch() 方法。因此,我正在尝试使用在 Stackoverflow 上其他地方发布的 shim 作为答案(可在此处获得: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");
    };
};
4

1 回答 1

1

回答我自己的问题:提供的 shim 似乎放置了一个损坏的 setter 函数。特别是,除非处理函数返回有意义的东西(它可能不返回),否则该属性将设置为未定义。更换

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

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

似乎完成了这项工作。

附带说明一下,这个特殊的垫片很巧妙,但有几个限制:

  • 依赖于监视值的代码可能需要一段时间才能工作,因此如果使用它们作为标志,在关键操作之后更改监视值是很好的。

  • 您不能将多个处理程序添加到一个值。

于 2011-08-10T02:19:59.357 回答