覆盖 JavaScript (window) 函数

Override JavaScript (window) Function

我想重写一个由 javascript 插件创建的函数。我知道如何覆盖常规 window 函数,但这是不同的。我不确定如何命名它,但该函数的结构如下:

window.something.function

我不知道如何覆盖它。我尝试了以下方法:

var originalFunction = window.something.function;
window.something.function = function(parameter) {
    alert('called');
    return originalFunction(parameter);
}

但它不起作用。

有人知道解决方案吗?

编辑: 有人告诉我我的问题不清楚,我用插件的实际名称再次编辑了它。

该插件旨在用作:

var myColor = new jscolor(target, options)

当使用这个时,有一个函数"inside" the object "jscolor" 在设置目标元素的值时被调用。我想覆盖该函数以添加额外的功能而不更改原始 js 文件。

代码:

if (!window.jscolor) { window.jscolor = (function () {


var jsc = {
    .....
    jscolor : function (targetElement, options) {
        ....
        //Function I want to change:
        this.exportColor = function (flags) {
            if (!(flags & jsc.leaveValue) && this.valueElement) {
                var value = this.toString();
                if (this.uppercase) { value = value.toUpperCase(); }
                if (this.hash) { value = '#' + value; }

                if (jsc.isElementType(this.valueElement, 'input')) {
                    this.valueElement.value = value;
                } else {
                    this.valueElement.innerHTML = value;
                }
            }
        }
    }
};

我目前的尝试:

var origJsColor = jscolor.exportColor;
jscolor.exportColor = function(flags) {
    console.log('called');
    return origJsColor(flags);
}

和上面的 window 尝试。

函数

function a() {alert(this)} // will print `window` obejct

在 window 范围内定义。也就是说,它是window的方法。如果您将函数定义为另一个对象中的方法,则您的 more difficult 情况来自 this 与 window 不同的事实。

var a = {method: function() {alert(this)}} 

您调用 a.method() 但再次看到相同的 window。您需要 bind 您的函数到父对象以使其竞争方法。

您显示的 jscolor 代码创建了一个对象,该对象具有自己的 exportColor 副本(为每个对象创建一个)。因此,要替换它,您必须在创建实例时在每个实例上替换它。

您可以按照您展示的方式一次性完成,只需使用实例而不是插件函数,并使用 Function#call 以正确的方式调用它 this :

// Get the instance
var c = new jscolor(target, options)

// Update it
var origExportColor = c.exportColor;
c.exportColor = function(flags) {
    console.log('called');
    return origExportColor.call(c, flags); // Note the changes on this line
};

或者代替

return origExportColor.call(c, flags);

你可能会用到

return origExportColor.apply(c, arguments);

...如果有任何机会使用除一个参数以外的任何其他参数调用该函数。 (arguments 是一个神奇的伪数组,包含用于调用函数的参数。)

如果你想为你可能创建的 all 个实例做那个,你可以在 jscolor 前面放一个 facade 来对每个实例做这个:

var realJscolor = jscolor;
jscolor = function() {
    // Call the real function, passing along all the arguments we
    // get automatically (`arguments` is a magic pseudo-array)
    var retVal = realJscolor.apply(this, arguments);

    // If it returned a non-`null` object, we want to use that instead
    // of `this`; if not, we keep using `this`
    if (!retVal || typeof retVal !== "object") {
        retVal = this;
    }

    // Slip in our version of exportColor
    var origExportColor = retVal.exportColor;
    retVal.exportColor = function(flags) {
        console.log('called');
        // (Maybe use `apply` here instead)
        return origExportColor.call(retVal, flags);
    };

    // Return the result, in case the real function overrode `this`
    return retVal;
};
jscolor.prototype = realJscolor.prototype;

然后正常使用jscolor即可:

var c = new jscolor(target, options);

retVal 的原因是,虽然通常 new 表达式的结果是对 new 创建的新对象的引用,但构造函数 可以 return 非null 对象引用,如果是,则new 表达式的结果是该对象引用。这就是我们检查 realJscolor.

的 return 值的原因

当然,这意味着 所有 在使用全局的页面上使用 jscolor 现在将使用您更新的函数。如果你不想那样,只需使用你自己的名字,不要覆盖 jscolor:

var myColor = function() {
    var retVal = jscolor.apply(this, arguments);
    // ...and so on...
    return retVal;
};
myColor.prototype = jscolor.prototype;

用法:

var c = new myColor(target, options);