2016-06-19 5 views
0

Ich versuche, einige Benutzercripts in JavaScript zu schreiben, um mit Browsererweiterungen verwendet zu werden.In einem externen Skript definierte übergeordnete Funktionen

In einer Website versuchte ich, mit Object.defineProperty eine in einem externen Javascript definierte Funktion zu überschreiben. aber es scheint, dass dies das externe Skript bricht, weil andere Codes in den externen Skripten (die für die ursprüngliche Website essentiell sind) nicht so gut ausgeführt werden.

<html> 
    <head> 
    <!-- injected script, injected via Userscript --> 
    <script> 
     Object.defineProperty(window, 'originalFunction', { get: function() { return overridingFunction; } }); 
    </script> 
    <!-- injection end --> 
    </head> 
    <body> 
    <script src="/external-javascript.js"> 
    <script> originalFunction(); </script> 
    <script> anotherEssentialFunction(); </script> 
    </body> 
</html> 

und http://domain/external-javascript.js sieht aus wie dieses“

... 
function originalFunction() { 
    some codes here; 
} 
... 
function anotherEssentialFunction() { 
    .... 
} 

und dies wurde verhindert anotherEssentialFunction aus ausgeführt wird. In der Konsole sehe ich TypeError: can't redefine non-configurable property originalFunction und ReferenceError: anotherEssentialFunction is not defined Ist das in dieser Situation zu erwarten, oder sollte es anders sein Problem, das es verursacht, das hier nicht beschrieben wird? Wie kann ich ursprüngliche Funktion sicher außer Kraft setzen, ohne solch einen Fehler zu verursachen?

Antwort

1

Object.defineProperty nimmt den Name eine Funktion als Parameter, so müßten Sie diese stattdessen tun:

Object.defineProperty(window, 'originalFunction', { 
    get: function() { 
    return overridingFunction; 
    } 
}); 

Oder wenn das die alle Getter tun, einfach:

window.originalFunction = overridingFunction; 

Aber wenn die anderen Funktionen benötigen Um die ursprüngliche Funktion aufzurufen, können Sie sie nicht wirklich überschreiben, ohne die Funktionen zu unterbrechen, die auf ihrem Verhalten beruhen. Wenn Sie nur versuchen, benutzerdefinierte Code zusätzlich zu den ursprünglichen Code auszuführen, können Sie dies tun:

var origFn = window.originalFunction; 
window.originalFunction = function() { 
    customFunction(); 
    origFn.apply(this, [].slice.call(arguments)); 
}; 

aktualisieren:

Basierend auf Ihren Kommentar, es klingt wie du bist Sie möchten nicht nur die ursprüngliche Funktion außer Kraft setzen, sondern auch verhindern, dass das externe Skript diese Funktion neu definiert. Sie können vielleicht fügen Sie eine no-op Setter, um das externe Skript zu vermeiden, einen Fehler, wenn ich versuche, sie zu definieren:

Object.defineProperty(window, 'originalFunction', { 
    get: function() { 
    return overridingFunction; 
    }, 
    set: function(ignored) { } 
});  
+0

(I enthalten, obwohl Anführungszeichen, bearbeitet, danke für den Hinweis auf vergaß) Es scheint, dass Wenn ich 'window.originalFunction = overridingFunction' verwende, wird die ursprüngliche Funktion vom externen Skript neu definiert, und dies war der Grund für mich, Getter zu verwenden. In meiner Situation wird die ursprüngliche Funktion tatsächlich in anderen Skripten im externen Skript mehrmals aufgerufen, aber ich dachte, sie sollten mit der neuen Überschreibungsfunktion arbeiten, oder vielleicht ist dies nicht wahr und ist die Ursache des Problems .. Ich werde es versuchen dein letzter Vorschlag. Vielen Dank! – user545

+0

Ich habe versucht, wie Sie in der aktualisierten Antwort gesagt haben, und das entfernt einen Konsolenfehler 'TypeError: kann die nicht konfigurierbare Eigenschaft originalFunction nicht neu definieren. Allerdings ist 'anotherEssentialFunction' noch nicht definiert und ich würde gerne wissen, wie ich das beheben kann. – user545

Verwandte Themen