我有几种方法需要以基本相同的方式包装在新方法中。我的第一个解决方案不起作用,我理解为什么,但我不知道是否有一个简单的解决方案来解决这个问题,或者是否无法以我想要的方式完成。
这是一个例子。我有对象a-c有一个onClick方法。我需要在onClick方法之前执行一些代码。我尝试了以下方法:
// objects a-c
a = {onClick : function () { console.log('a'); }};
b = {onClick : function () { console.log('b'); }};
c = {onClick : function () { console.log('c'); }};
// first try
var arr = [a, b, c]
for (var i = 0; i < arr.length; i++) {
var oldOnClick = arr[i].onClick;
arr[i].onClick = function () {
// new code here
oldOnClick();
}
}
// outputs 'c'
// what i want is to maintain a reference to the original method
// so in this case, execute my new code and output 'a'
a.onClick();
这不起作用,因为在调用新方法时,oldOnClick将指向上一次迭代的方法,而不是分配时的to方法。
我有一个简单的解决方案吗?
答案 0 :(得分:3)
你需要的是关闭:
for(var i=0, l=arr.length; i<l; i++){
(function(i){
var oldOnclick = arr[i].onClick;
//etc.
})(i);
}
答案 1 :(得分:1)
Javascript绑定规则很奇怪。真的,javascript很奇怪。
我不知道我会用这个 方式来修复它,但是通过引入一个子函数,你可以引入另一个绑定,从而解决这个特殊问题。
您的(针对quick-y Chrome黑客修改)代码变为:
a = {onClick : function () { alert('a'); }};
b = {onClick : function () { alert('b'); }};
c = {onClick : function () { alert('c'); }};
var arr = [a, b, c]
for (var i = 0; i < arr.length; i++) {
var oldOnClick = arr[i].onClick;
arr[i].onClick = bind(oldOnClick);
}
a.onClick();
b.onClick();
c.onClick();
function bind(oldFunc)
{
return function () {
//New Code
oldFunc();
}
}
以上代码会抛出三个警报:a,b,c。替换'//新代码'的任何内容都将在合适的时间运行。
答案 2 :(得分:1)
你是否试过Javascript的一些AOP框架?例如使用jQuery AOP插件:
jQuery.aop.before( {target: String, method: 'replace'},
function(regex, newString) {
alert("About to replace string '" + this + "' with '" + newString +
"' using regEx '" + regex + "'");
}
);
同时检查here。
答案 3 :(得分:0)
var a = {onClick : function () { console.log('a'); }};
var b = {onClick : function () { console.log('b'); }};
var c = {onClick : function () { console.log('c'); }};
var arr = [a, b, c];
for (var i = 0; i < arr.length; i++) {
var oldOnClick = arr[i].onClick;
arr[i].onClick = wrapHandler(oldOnClick);
}
function wrapHandler(handler) {
return function() {
console.log("New stuff");
handler();
}
}
a.onClick(); // outputs "New stuff" then "a"
b.onClick(); // outputs "New stuff" then "b"
b.onClick(); // outputs "New stuff" then "c"