为什么https://gist.github.com/384583,watch()和unwatch()的垫片在phantomjs中不起作用?[英] Why doesn't the shim for watch() and unwatch() at https://gist.github.com/384583 work in phantomjs?

问题描述

我正在做一些服务器端的 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");
    };
};

推荐答案

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

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

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

似乎完成了这项工作.

顺便说一句,这个特殊的垫片很巧妙,但也有一些限制:

  • 依赖于监视值的代码可能需要一段时间才能工作,因此如果将监视值用作标志,则最好在关键操作之后更改监视值.

  • 您不能向一个值添加多个处理程序.

本文地址:https://www.itbaoku.cn/post/1739976.html