2013-07-18 35 views
1

有没有方法在Javascript中调用函数调用之前和之后?我有这样的事情:JavaScript之前()和之后()过滤器的Ruby样式

var A = { 

    a1: function() { 

    }, 
}; 

var B = { 

    b1: function() { 

    } 
}; 

A.a1(); 
B.b1(); 
//so on .. 

我需要在每种方法之前和之后发生的事情。我可以在函数前后分别调用它们,但是我必须在代码中经常这样做,并且不想重复自己。

更新: 在红宝石

before_filter :some_function 
after_filter :some_other_function 

将每个函数调用之后,这些类和some_other_function每个函数调用之前执行some_function。这在Rails的应用程序控制器中也找不到。

+1

为每个对象调用'before'和'after'函数,在函数的第一行调用'before',在结尾调用'after'函数? – tymeJV

+0

如果你想解释Ruby中'before'和'after'函数的作用,你可能会得到更多的帮助。 – Shawn31313

回答

1

试试这个改变对象的所有功能:

var beforeAll = function(o, f) { 
    for (var p in o) { 
    if (o.hasOwnProperty(p) && typeof(o[p]) === "function") { 
     o[p] = (function(oldF) { 
     return function() { 
      f.apply(this, arguments); 
      return oldF.apply(this, arguments); 
     }; 
     }(o[p])); 
    } 
    } 
}; 

var A = { 
    func1: function() {console.log('func1')}, 
    func2: function() {console.log('func2')} 
}; 

beforeAll(A, function() {console.log('before')}); 

A.func1(); 
A.func2(); 

(您可以创建一个类似的afterAll)。

小提琴here

请注意,您需要捕获循环中的旧函数将其正确绑定。更多信息here

0

如果保存的原单功能之后(或之前)调用它:

var A = { 

    a1: function() { 

    } 
}; 

var orginal = A.a1 
A.a1 = function(){ 
    // the before code 
    orginal.apply(this, arguments) 
} 

所有道具

for(prop in A){ 
    var orginal = prop 
    A[prop] = function(){ 
    //before code 
    orginal.apply(this, arguments) 
    } 
} 

我离开类型检查作为读者的傩: )

+0

是否有可能为一个对象中的所有函数执行此操作?所以像'for(A中的键){if(typeof key == function){//保存原始并定义一个新的}}' – Deepak

+0

是的,我更新了我的安装程序 – VeXii

+0

您应该检查属性是否为函数,使用适用于第一个片段。并注意“这个”的价值:) – Ivancho

2

您可以编写一个枚举对象的字段并将其函数封装为新函数的函数:

function addBefore(obj, func) { 
    for (var prop in obj) { 
     if (obj.hasOwnProperty(prop) && typeof obj[prop] === 'function') { 
      (function() { 
       var oldFunc = obj[prop]; 
       obj[prop] = function() { 
        func.apply(obj, arguments); 
        return oldFunc.apply(obj, arguments);    
       } 
      }()); 
     } 
    } 
} 
var A = { 

    a1: function (a, b) { 
    alert('A.a1'); 
    return a + b; 
    }, 
    a2: function (a, b) { 
    alert('A.a2'); 
    return a + b; 
    } 
}; 
addBefore(A, function (a, b) { 
    alert('before ' + a + ', ' + b); 
}); 
A.a1(1, 2); 
A.a2(3, 4); 

以类似的方式,您可以编写函数addAfter,只需将两个调用切换到apply()函数即可。

+1

+1我做了[完全像你](http://jsfiddle.net/LTCpj/1/).... –

+0

我知道我接受了这个答复,但我遇到了这个并发症。当A有两个方法或多个方法时,旧的函数引用总是返回对象中的最后一个函数,而不是相应的函数。请参阅我在http://jsfiddle.net/LTCpj/3/上对@Jordão的小提琴所做的更新。有没有办法避免这种情况? – Deepak

+1

@Deepak:很好!修复它[这里](http://stackoverflow.com/a/17756830/31158)。 –

0

在JavaScript中,约定是使用回调这种事情。所以,如果你想只陆续解雇一个功能,它会是这个样子:

var a1 = function(callback){ 
    console.log('doing function things la la'); 
    callback(); 
} 

现在,当你调用a1功能,你会做这样的事情:

a1(function(){ 
    console.log('this is only printed at the end!'); 
}); 

我想,你可以在函数中添加第二个参数,在我猜测之前,这个函数更像是一个call,但是你不会经常看到这个参数。

如果你正在讨论的是在大量没有回调的方法之前让某个函数运行,我认为最好的方法就是用一个接受你的主函数作为函数的函数来包装它们回调,这样的事情:

var a1 = function(){ console.log('a1'); } 
var a2 = function(){ console.log('a2'); } 
var a3 = function(){ console.log('a3'); } 
var a4 = function(){ console.log('a4'); } 

var before_filter = function(callback){ 
    console.log('doing some stuff before whoo!'); 
    callback(); 
} 

[a1, a2, a3, a4].map(function(fn){ 
    before_filter(fn); 
}); 

让我知道这是不是你以后有什么,我很乐意添加更多选项 - 有来处理这个问题许多潜在的方式,它只是取决于你究竟在寻找什么。将它做成像ruby一样干净是很困难的,因为before_filters本身并没有内置到JavaScript中,但是看看最后一个例子,你可以看到它很容易让它变得非常接近。一个比较另类类似于上一个:

var a1 = function(){ console.log('a1'); } 
var a2 = function(){ console.log('a2'); } 
var a3 = function(){ console.log('a3'); } 
var a4 = function(){ console.log('a4'); } 
var before = function(){ console.log('doing before stuff'); } 

var before_filter = function(before_fn, fn){ 
    before_fn(); 
    fn(); 
} 

[a1, a2, a3, a4].map(function(fn){ 
    before_filter(before, fn); 
});