2016-06-09 70 views
1

我想重写正在由JavaScript插件创建的函数。我知道如何覆盖常规的窗口函数,但这是不同的。我不知道如何命名它,但该功能的结构是这样的:重写JavaScript(窗口)函数

window.something.function 

我不知道如何重写。我试过以下内容:

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

但它不工作。

有人知道解决方案吗?

编辑: 正如我被告知我的问题不清楚,我已经使用插件的实际名称再次编辑它。

该插件是指被用作:当该正在使用

var myColor = new jscolor(target, options) 

,有一个功能“内部”对象“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); 
} 

和窗口上方的尝试。

+0

你可以尝试运行'window.something.function()'立即在你的函数定义之后,看你定义的函数是否被实现。 –

+0

我更新了我的问题。 @JimmyKo感谢您的回复。我的函数被调用(这是显而易见的),但我得到的错误“originalFunction”不是一个函数。 – stefan1294

+0

@ T.J.Crowder道歉。我希望现在更清楚。 – stefan1294

回答

1

您显示的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是包含用来调用该函数的参数的魔法伪阵列。)

如果你想这样做的所有例如,你可以创建,你可以把一个门面在jscolor前面做,要每一个实例:

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创建的新对象的引用,构造函数可以返回非对象引用,如果是,则new表达式的结果是该对象引用。这就是为什么我们检查realJscolor的返回值。

当然,这意味着全部使用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); 
+1

非常感谢你为这个优秀的解释。我通过这个答案了解了很多。 – stefan1294

0

功能

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

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

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

你调用a.method()但是再次看到相同的窗口。您需要将您的功能bind添加到父对象中,以使其成为竞争方法。