2

我有几种方法需要以基本相同的方式包装在新方法中。我的第一个解决方案不起作用,我明白为什么,但我不知道是否有一个简单的解决方案可以解决这个问题,或者是否不能按照我想要的方式完成。

这是一个例子。我有具有 onClick 方法的对象 ac。我需要在 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 方法。

有没有我忽略的简单解决方案?

4

4 回答 4

3

你需要的是关闭:

for(var i=0, l=arr.length; i<l; i++){
 (function(i){
   var oldOnclick = arr[i].onClick; 
   //etc.
 })(i);
}
于 2009-06-21T09:08:42.767 回答
1

Javascript 绑定规则很奇怪。真的,javascript 很奇怪。

我不知道我会称之为修复它方法,但是通过引入一个子函数,您可以引入另一个绑定,从而解决这个特定问题。

您的(针对快速 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。任何替换“//新代码”的东西都将在正确的时间运行。

于 2009-06-21T09:08:49.773 回答
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 + "'");
  }
);

也在这里检查。

于 2009-06-21T09:11:31.420 回答
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"
于 2009-06-21T15:48:46.097 回答