为什么 https://gist.github.com/384583 上的 watch() 和 unwatch() 的垫片在 phantomjs 中不起作用?
我正在做一些服务器端 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");
};
};
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.
However, it lacks an Object.watch() method, which I'd rather like to have. 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.
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?
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");
};
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
回答我自己的问题:提供的垫片似乎将损坏的设置器功能放在适当的位置。特别是,除非处理程序函数返回有意义的内容(很可能不会),否则该属性将设置为未定义。替换
为
似乎可以完成工作。
顺便说一句,这个特殊的填充程序很巧妙,但有一些限制:
依赖监视值的代码可能需要一段时间才能工作,因此最好在关键操作之后更改监视值如果将它们用作标志。
您无法向一个值添加多个处理程序。
To answer my own question: the provided shim seems to put a broken setter function in place. In particular, unless the handler function returns something meaningful (which it may well not), the property gets set to undefined. Replacing
with
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.