简体   繁体   English

为什么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?

I'm doing some server-side javascript bits and pieces that essentially need both access to websites' full DOMs and the ability to open sites cross-domain, and at least so far, PhantomJS seems the best tool for the job. 我正在做一些服务器端的javascript部分,基本上需要访问网站的完整DOM和跨域打开网站的能力,至少到目前为止,PhantomJS似乎是这项工作的最佳工具。

However, it lacks an Object.watch() method, which I'd rather like to have. 但是,它缺少一个我更喜欢的Object.watch()方法。 As such, I'm trying to use the shim posted as an answer elsewhere on Stackoverflow (available here: https://gist.github.com/384583 ) to give me access to just such methods. 因此,我正在尝试使用在Stackoverflow上的其他地方发布的垫片(可在此处获取: https//gist.github.com/384583 )来让我访问这些方法。

It isn't working. 它不起作用。

It's also well beyond my level of JavaScript understanding - so I'm wondering if anyone could help me understand both exactly what it's doing, and why it might not be working? 这也远远超出了我对JavaScript的理解水平 - 所以我想知道是否有人可以帮助我理解它正在做什么,以及为什么它可能不起作用?

Thanks for the help, 谢谢您的帮助,

Toby 托比

(Code quoted below: (以下引用的代码:

// 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;
    };
}

And my test code: 我的测试代码:

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");
    };
};

To answer my own question: the provided shim seems to put a broken setter function in place. 回答我自己的问题:提供的垫片似乎使一个破坏的setter功能到位。 In particular, unless the handler function returns something meaningful (which it may well not), the property gets set to undefined. 特别是,除非处理函数返回有意义的东西(它可能不是),否则属性将设置为undefined。 Replacing 更换

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

with

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

seemed to do the job. 似乎做了这个工作。

As a side note, this particular shim is ingenious but includes a couple of limitations: 作为旁注,这个特殊的垫片是巧妙的,但包括一些限制:

  • Code relying on a watched value may take a while to work, so it's good to change watched values after critical operations if using them as flags. 代码依赖于观看值可能需要一段时间来工作,所以它的好,如果用它们作为标志关键操作更改观看值。

  • You can't add multiple handlers to a value. 您无法向值添加多个处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM