引用原始函数时覆盖JavaScript函数

2020/10/29 10:42 · javascript ·  · 0评论

我有一个a()要覆盖的函数,但也有一个a()要根据上下文按顺序执行的功能。例如,有时在生成页面时,我会想要像这样覆盖:

function a() {
    new_code();
    original_a();
}

有时像这样:

function a() {
    original_a();
    other_new_code();
}

我如何original_a()从最重要的方面得到它a()可能吗?

我知道很多人都建议不要以这种方式替代替代。我是在问这种方式。

您可以执行以下操作:

var a = (function() {
    var original_a = a;

    if (condition) {
        return function() {
            new_code();
            original_a();
        }
    } else {
        return function() {
            original_a();
            other_new_code();
        }
    }
})();

original_a在匿名函数内部进行声明可以防止其混乱全局名称空间,但可以在内部函数中使用它。

就像评论中提到的Nerdmaster一样,一定要()在最后加上。您想调用外部函数并将结果(两个内部函数之一)a存储在,而不是将外部函数本身存储在中a

代理模式可以帮助你:

(function() {
    // log all calls to setArray
    var proxied = jQuery.fn.setArray;
    jQuery.fn.setArray = function() {
        console.log( this, arguments );
        return proxied.apply( this, arguments );
    };
})();

上面的代码将其包装在一个函数中,以隐藏“代理”变量。它将jQuery的setArray方法保存在一个闭包中并覆盖它。然后,代理将所有调用记录到该方法,并将该调用委托给原始方法。使用apply(this,arguments)可确保调用者无法注意到原始方法与代理方法之间的区别。

谢谢大家,代理模式确实有所帮助.....实际上,我想调用全局函数foo ..在某些页面中,我需要做一些检查。所以我做了以下。

//Saving the original func
var org_foo = window.foo;

//Assigning proxy fucnc
window.foo = function(args){
    //Performing checks
    if(checkCondition(args)){
        //Calling original funcs
        org_foo(args);
    }
};

谢谢,这真的帮了我

您可以使用类似以下的结构来覆盖函数:

function override(f, g) {
    return function() {
        return g(f);
    };
}

例如:

 a = override(a, function(original_a) {
      if (condition) { new_code(); original_a(); }
      else { original_a(); other_new_code(); }
 });

编辑:修正了一个错字。

传递任意参数:

a = override(a, function(original_a) {
    if (condition) { new_code(); original_a.apply(this, arguments) ; }
    else { original_a.apply(this, arguments); other_new_code(); }
});

@Matthew Crumley提供的答案是利用立即调用的函数表达式,以将较旧的“ a”函数关闭到返回函数的执行上下文中。我认为这是最好的答案,但就我个人而言,我更愿意将函数“ a”作为参数传递给IIFE。我认为这是可以理解的。

   var a = (function(original_a) {
        if (condition) {
            return function() {
                new_code();
                original_a();
            }
        } else {
            return function() {
                original_a();
                other_new_code();
            }
        }
    })(a);

上面的示例未正确应用thisarguments正确传递给函数重写。下划线_.wrap()包装现有函数,应用thisarguments正确传递请参阅:http//underscorejs.org/#wrap

我有一些其他人编写的代码,想在代码中找不到的函数上添加一行。因此,作为一种解决方法,我想覆盖它。

但是,没有一种解决方案对我有用。

这是我的情况下有效的方法:

if (typeof originalFunction === "undefined") {
    originalFunction = targetFunction;
    targetFunction = function(x, y) {
        //Your code
        originalFunction(a, b);
        //Your Code
    };  
}

我为类似的情况创建了一个小助手,因为我经常需要覆盖多个库中的函数。该帮助器接受“命名空间”(函数容器),函数名称和重写函数。它将用新的命名空间替换引用的命名空间中的原始函数。

新函数将原始函数作为第一个参数,并将原始函数作为其余参数。它将每次都保留上下文。它也支持void和non-void函数。

function overrideFunction(namespace, baseFuncName, func) {
    var originalFn = namespace[baseFuncName];
    namespace[baseFuncName] = function () {
        return func.apply(this, [originalFn.bind(this)].concat(Array.prototype.slice.call(arguments, 0)));
    };
}

在Bootstrap中的用法例如:

overrideFunction($.fn.popover.Constructor.prototype, 'leave', function(baseFn, obj) {
    // ... do stuff before base call
    baseFn(obj);
    // ... do stuff after base call
});

我没有创建任何性能测试。它可能会增加一些不必要的开销,根据情况的不同,开销可能很大,也可能不会很大。

在我看来,最重要的答案是不可读/不可维护的,其他答案不能正确地绑定上下文。这是使用ES6语法解决这两个问题的可读解决方案。

const orginial = someObject.foo;
someObject.foo = function() {
  if (condition) orginial.bind(this)(...arguments);
};

因此,最终我的答案是一个解决方案,使我可以使用_this变量指向原始对象。我创建了一个“ Square”的新实例,但是我讨厌“ Square”生成其大小的方式。我认为它应该符合我的特定需求。但是,为了做到这一点,我需要正方形具有更新的“ GetSize”函数,该函数的内部调用该正方形中已经存在的其他函数,例如this.height,this.GetVolume()。但是为了做到这一点,我需要做到这一点而没有任何疯狂的破解。所以这是我的解决方案。

其他一些对象初始化器或帮助器函数。

this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(
  this.viewerContainer)
var viewer = this.viewer;
viewer.updateToolbarButtons =  this.updateToolbarButtons(viewer);

在另一个对象中起作用。

updateToolbarButtons = function(viewer) {
  var _viewer = viewer;
  return function(width, height){ 
blah blah black sheep I can refer to this.anything();
}
};

不知道它是否在所有情况下都能正常工作,但是在我们的案例中,我们试图覆盖describeJest中函数,以便我们可以解析名称,并在describe满足某些条件的情况下跳过整个块。

这对我们有用:

function describe( name, callback ) {
  if ( name.includes( "skip" ) )
    return this.describe.skip( name, callback );
  else
    return this.describe( name, callback );
}

这里至关重要的两件事:

  1. 我们不使用箭头功能() =>

    箭头函数会更改对的引用this,我们需要将其作为文件的this

  2. 使用this.describeandthis.describe.skip代替justdescribedescribe.skip

同样,不确定是否对任何人有价值,但我们最初试图摆脱Matthew Crumley的 出色回答,但需要使我们的方法成为函数并接受参数,以便在条件条件下解析它们。

本文地址:http://javascript.askforanswer.com/yinyongyuanshihanshushifugaijavascripthanshu.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!