【问题标题】:Can you reset function input order efficiently?你能有效地重置函数输入顺序吗?
【发布时间】:2013-07-03 14:41:32
【问题描述】:

我的想法是:我希望能够做到这一点,以便我可以更改输入在函数中的重要性的顺序。假设普通函数如下所示:

var f = function(a,b,c,d){
    return a * b / c + d;
}

我希望能够重新定义该函数,这样当用户调用f(w,x,y,z) 时,如果变量(比如changed)为真,就好像用户调用了f(w,z,y,x)! (不是具体的倒序,只是和原函数的顺序不同)

如果我想编写一个单独的函数,我可以这样做:

var newF = function(a,b,c,d){
    if(changed === true){
        return f(c,d,b,a);
    }
    else{
        return f(a,b,c,d);
    }
}

然后将所有f 调用替换为newF 调用,但这不是我要的。

是否可以重新定义与实际函数同名的函数,如何实现?如果我不能,请解释为什么不能。

说明:

我想这样做的原因是因为我有一个应用程序,该应用程序具有使一切听起来自然的功能(例如直线中的点是直的),但如果我切换某些值,它会创建一个有趣的、不切实际的, 情况,我认为这将是一个有趣的选择。我上面的选项是可行的,我可以使用它,但我只是想知道是否可以将它保留在相同的函数名称中

【问题讨论】:

  • 我不确定我是否理解您为什么要这样做。您希望通过像这样动态更改参数的顺序来实现什么?
  • 这有必要吗?根据断开连接变量的值,具有具体函数的行为会有所不同,这听起来像是灾难的秘诀
  • 也许您希望函数接受一个对象,其中每个属性都是一个参数,而不是接受多个参数。那么调用者就不用担心顺序了。
  • 你这样做实际上是想解决什么问题,因为我很确定这是一个糟糕的主意。
  • 您可以备份旧功能然后重新定义它。 var _oldF = f; var f = function(){ // call _oldF }.

标签: javascript function


【解决方案1】:

是否可以重新定义一个与实际函数同名的函数,如何实现?

是的,您可以再次分配给它的标识符:

f = function(a,b,c,d) {
    if (changed)
        return a * d / c + b;
    else
        return a * b / c + d;
};

如果你不知道具体的内容(但想截取它的参数)而需要调用实际的函数,你可以这样做

f = (function(oldF) {
    return function(a,b,c,d){
        if (changed)
            return oldF(c,d,b,a);
        else
            return oldF(a,b,c,d);
    };
})(f);

【讨论】:

  • 它是一个自调用函数
  • 强调它是一个立即调用的函数表达式。他们实际上是not necessary
【解决方案2】:
var oldF = f;

f = function( ... ){
    // do stuff
    oldF(...);
};

【讨论】:

    【解决方案3】:

    使用在运行时返回正确函数的工厂方法。

    【讨论】:

      【解决方案4】:

      除了“你为什么想要”之外,你还可以这样做:

      var changed = false;
      
      var f = function(a,b) {
          console.log("original function: " + a + "," + b);
      }
      
      f = (function(original) {
          return function(a,b) {
              console.log("new function");
               if (changed) {
                   console.log("order changed");
                   original(b,a);
               }
               else {
                    original(a,b);
               }
           }
      })(f);
      
      f(1,2);
      changed = true;
      f(1,2);
      

      将输出(在控制台中):

      new function 
      original function: 1,2 
      new function 
      order changed 
      original function: 2,1 
      

      fiddle

      【讨论】:

        【解决方案5】:

        好的,只要你定义了这样的函数:

        var f = function(...){...};
        

        然后您可以轻松地覆盖它。但是当你这样做时:

        function f(...){...}
        

        简单的解释是,当你用function f(...){... 声明函数时,编译器将首先以这种方式查找每个声明的函数,然后运行你的代码。另一方面,声明为变量 f 将在运行时而不是在预处理期间存储函数。 因此这样声明:

        function f(){
            console.log('a');
        };
        f();
        function f(){
            console.log('b');
        }
        
        f();
        

        将输出b b, fiddle 虽然这样:

        var f = function () {
            console.log('a');
        };
        f();
        f = function () {
            console.log('b');
        }
        
        f();
        

        将输出a bfiddle

        现在,我从不将参数放在示例中,因为 JS 不关心类型和参数大小。 imo 最好的方法是这样做:

        var myProject = {};
        
        myProject.fn = {
        
            f: function(args,options){
                //in your case while you need a,b,c,d you can use the args array to store them
                //options to define the 'changed' thing or whatever you need
                }
        
        }
        

        【讨论】:

        • 嗯,他没有函数声明?顺便说一句,你的第二个 sn-p 确实输出 a b 而不是 a a
        猜你喜欢
        • 1970-01-01
        • 2022-11-10
        • 2020-04-20
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 2018-07-29
        • 1970-01-01
        相关资源
        最近更新 更多