我需要创建一个间隔包装器来跟踪它是否已被清除。
传递给区间回调的参数数量应该是可变的。所以这是我为测试它而实现的代码(不工作):
function MyInterval() {
var id = setInterval.apply(this, arguments); // NOT VALID!!
this.cleared = false;
this.clear = function() {
this.cleared = true;
clearInterval(id);
};
}
var x = 2;
var y = 3;
var fn = function() {
x = x + y;
console.log(x);
};
var interval = new MyInterval(fn, 5000, x, y);

答案 0 :(得分:1)
在对setInterval
的调用中,this
必须引用全局对象,因此在构造函数中需要this
而不是window
:
var id = setInterval.apply(window, arguments);
// here -------------------^
(或者在宽松模式下,您可以使用undefined
或null
。)
然后它起作用,至少在setInterval
是一个真正的JavaScript函数的浏览器上,因此有apply
:
function MyInterval() {
var id = setInterval.apply(window, arguments);
this.cleared = false;
this.clear = function() {
this.cleared = true;
clearInterval(id);
};
}
var x = 2;
var y = 3;
var fn = function() {
x = x + y;
log(x);
};
var interval = new MyInterval(fn, 500, x, y);
setTimeout(function() {
interval.clear();
}, 3000);
function log(msg) {
var p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
注意但是,主机提供的功能只需要是可调用的,它们 不需要从Function.prototype
继承,所以它们是不需要/保证apply
。现代浏览器确保它们可以,但早期的浏览器(例如IE8)没有。我无法谈论apply
对setInterval
的支持程度如何。
如果您需要支持可能没有它的浏览器,只需使用您自己的功能:
function MyInterval(handler, interval) {
var args = Array.prototype.slice.call(arguments, 2);
var tick = function() {
handler.apply(undefined, args);
};
var id = setInterval(tick, interval);
this.cleared = false;
this.clear = function() {
this.cleared = true;
clearInterval(id);
};
}
这也有一个优点,即它在setInterval
(相当旧的)上不支持其他args的浏览器上也能正常工作。
示例:
function MyInterval(handler, interval) {
var args = Array.prototype.slice.call(arguments, 2);
var tick = function() {
handler.apply(undefined, args);
};
var id = setInterval(tick, interval);
this.cleared = false;
this.clear = function() {
this.cleared = true;
clearInterval(id);
};
}
var x = 2;
var y = 3;
var fn = function() {
x = x + y;
log(x);
};
var interval = new MyInterval(fn, 500, x, y);
setTimeout(function() {
interval.clear();
}, 3000);
function log(msg) {
var p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
您可能想要使用新的ES2015传播运营商:
var id = setInterval(...arguments);
...但请注意,如果你进行了细分(现在你必须这样做),它最终会被apply
调用,因此你会遇到是否支持apply
的问题
答案 1 :(得分:1)
我建议您通过"选项"超时参数。
var MyInterval = (function(window) {
return function(callbackFn, timeout, options) {
var id = setInterval.apply(window, arguments);
this.cleared = false;
this.clear = function() {
this.cleared = true;
clearInterval(id);
};
}
}(window));
var fn = function(opts) {
opts.x += opts.y;
console.log('x = ', opts.x);
};
var opts = {
x: 2,
y: 3
};
var ms = 5000;
var interval = new MyInterval(fn, ms, opts);
// Bootstrap a custom logger. :)
console.log = function() {
var logger = document.getElementById('logger');
var el = document.createElement('LI');
el.innerHTML = [].join.call(arguments, ' ');
logger.appendChild(el);
logger.scrollTop = logger.scrollHeight;
}

body{background:#7F7F7F;}h1{background:#D7D7D7;margin-bottom:0;padding:0.15em;border-bottom:thin solid #AAA;color:#444}#logger{height:120px;margin-top:0;margin-left:0;padding-left:0;overflow:scroll;max-width:100%!important;overflow-x:hidden!important;font-family:monospace;background:#CCC}#logger li{list-style:none;counter-increment:step-counter;padding:.1em;border-bottom:thin solid #E7E7E7;background:#FFF}#logger li:nth-child(odd){background:#F7F7F7}#logger li::before{content:counter(step-counter);display:inline-block;width:1.4em;margin-right:.5em;padding:.25em .75em;font-size:1em;text-align:right;background-color:#E7E7E7;color:#6A6A6A;font-weight:700}

<h1>Custom HTML Logger</h1><ol id="logger"></ol>
&#13;
答案 2 :(得分:1)
我创建了一个实用程序函数而不是构造函数来解决您的问题。
class produit_produit(osv.osv):
"""le produit"""
_name = 'produit.produit'
_columns = {
'product_id': fields.char('product_id',size=30,required=True, help='product_id'),
'product_libelle': fields.char('product_libelle',size=60,required=True, help='product_libelle'),
'type': fields.char('type',required=True, help='type'),
'prix': fields.many2one('produitachete.produitachete',help='prix'),
}
produit_produit()
class produitachete_produitachete(osv.osv):
"""produit achete"""
_name = 'produitachete.produitachete'
_columns = {
'prix_achat': fields.char('prix_achat',size=30,required=True, help='prix_achat'),
}
produitachete_produitachete()
希望这有帮助。