这段代码中变量“tmp”的用途是什么?
What's the purpose for the variable `tmp` in this snippet?
我很难理解以下代码中变量 tmp
的意义:
$.extend($.Widget.prototype, {
yield: null,
returnValues: { },
before: function(method, f) {
var original = this[method];
this[method] = function() {
f.apply(this, arguments);
return original.apply(this, arguments);
};
},
after: function(method, f) {
var original = this[method];
this[method] = function() {
this.returnValues[method] = original.apply(this, arguments);
return f.apply(this, arguments);
}
},
around: function(method, f) {
var original = this[method];
this[method] = function() {
var tmp = this.yield;
this.yield = original;
var ret = f.apply(this, arguments);
this.yield = tmp;
return ret;
}
}
});
为什么不简单地使用函数局部变量 var yield
并在 around
方法中完全省略 tmp
?它有什么作用?这是常见的设计模式吗?
感谢您的提示。
显然该代码来自 Extending jQuery UI Widgets, which provides some useful context. That article refers to Avoiding Bloat in Widgets 作为代码的来源。但是,原始版本没有 tmp
变量。
我喜欢添加 tmp
,因为它避免了原始代码的副作用。考虑应该如何使用 around 函数:
YourWidgetObject.existingWidgetClass("around", "click", function(){
console.log("before"); //or any code that you want executed before all clicks
yield(); // executes existing click function
console.log("after"); //or any code that you want executed after all clicks
}
无论有无 tmp
杂耍,这都将按预期工作。 click
事件现在将在事件前后执行您的额外代码。
但是如果您不使用 tmp
恢复 yield
,对象的 public 方法 yield
现在将被重新定义。因此,如果有人有在使用 around
之后调用 YourWidgetObject.yield()
的奇怪想法,它将执行上次应用的任何现有方法 around
(在本例中,click
).
在要求澄清后添加:
假设您根本不恢复 yield
,也不将其设置为空。在上面的代码之后,你这样做:
YourWidgetObject.existingWidgetClass("before", "focus", function(){
yield(); // executes existing **click** function
}
yield
现在在焦点上执行点击功能,这是非常意外的行为。
您能否将 yield
设置为 null 而不是使用 tmp
恢复它?当然,就像现在一样,它不会有所作为。但由于您可能会更改或添加其他方法,因此让 around
方法不知道当前状态更为谨慎,即它不必知道 yield
在被调用时始终为 null。
作为旁注,我认为这是一个糟糕的 around
方法,因为围绕事件放置事物并不一定是它的作用 - 您可以调用 yield
任意多次,或者一点也不。对于真正的 around
方法更明智的做法是接受两个回调,一个在事件之前执行,一个在事件之后执行。这样一来,您就不需要首先公开 yield
方法。
around: function(method, before, after) {
var original = this[method];
this[method] = function() {
before();
original();
after();
}
}
我很难理解以下代码中变量 tmp
的意义:
$.extend($.Widget.prototype, {
yield: null,
returnValues: { },
before: function(method, f) {
var original = this[method];
this[method] = function() {
f.apply(this, arguments);
return original.apply(this, arguments);
};
},
after: function(method, f) {
var original = this[method];
this[method] = function() {
this.returnValues[method] = original.apply(this, arguments);
return f.apply(this, arguments);
}
},
around: function(method, f) {
var original = this[method];
this[method] = function() {
var tmp = this.yield;
this.yield = original;
var ret = f.apply(this, arguments);
this.yield = tmp;
return ret;
}
}
});
为什么不简单地使用函数局部变量 var yield
并在 around
方法中完全省略 tmp
?它有什么作用?这是常见的设计模式吗?
感谢您的提示。
显然该代码来自 Extending jQuery UI Widgets, which provides some useful context. That article refers to Avoiding Bloat in Widgets 作为代码的来源。但是,原始版本没有 tmp
变量。
我喜欢添加 tmp
,因为它避免了原始代码的副作用。考虑应该如何使用 around 函数:
YourWidgetObject.existingWidgetClass("around", "click", function(){
console.log("before"); //or any code that you want executed before all clicks
yield(); // executes existing click function
console.log("after"); //or any code that you want executed after all clicks
}
无论有无 tmp
杂耍,这都将按预期工作。 click
事件现在将在事件前后执行您的额外代码。
但是如果您不使用 tmp
恢复 yield
,对象的 public 方法 yield
现在将被重新定义。因此,如果有人有在使用 around
之后调用 YourWidgetObject.yield()
的奇怪想法,它将执行上次应用的任何现有方法 around
(在本例中,click
).
在要求澄清后添加:
假设您根本不恢复 yield
,也不将其设置为空。在上面的代码之后,你这样做:
YourWidgetObject.existingWidgetClass("before", "focus", function(){
yield(); // executes existing **click** function
}
yield
现在在焦点上执行点击功能,这是非常意外的行为。
您能否将 yield
设置为 null 而不是使用 tmp
恢复它?当然,就像现在一样,它不会有所作为。但由于您可能会更改或添加其他方法,因此让 around
方法不知道当前状态更为谨慎,即它不必知道 yield
在被调用时始终为 null。
作为旁注,我认为这是一个糟糕的 around
方法,因为围绕事件放置事物并不一定是它的作用 - 您可以调用 yield
任意多次,或者一点也不。对于真正的 around
方法更明智的做法是接受两个回调,一个在事件之前执行,一个在事件之后执行。这样一来,您就不需要首先公开 yield
方法。
around: function(method, before, after) {
var original = this[method];
this[method] = function() {
before();
original();
after();
}
}