122 votes

Ajout de code pour une fonction javascript par programmation

Je suis d'essayer de le personnaliser bibliothèque JS sans modifier l'original du code JS. Ce code charge dans un peu de JS externe des fichiers qui j'ai de l'accès à, et ce que je voudrais faire est de changer l'une des fonctions contenues dans le fichier d'origine sans avoir à copier et coller le tout dans le deuxième fichier JS.
Ainsi, par exemple, les limites de la JS pourrait avoir une fonction comme ceci:

var someFunction = function(){
    alert("done");
}

J'aimerais être capable de quelque sorte ou d'ajouter certains code JS dans cette fonction. La raison en est principalement que dans l'original intouchable JS la fonction est assez énorme et si le JS n'est jamais mis à jour, la fonction que j'ai remplacer par sera hors de date.

Je ne suis pas entièrement sûr que c'est possible, mais j'ai pensé que je voudrais vérifier.
Merci.

232voto

squint Points 28293

Si someFunction est disponible dans le monde entier, alors vous pouvez mettre en cache la fonction, créez votre propre, et avez vous l'appelez.

Donc, si c'est l'original...

someFunction = function() {
    alert("done");
}

Vous devrez faire cela...

someFunction = (function() {
    var cached_function = someFunction;

    return function() {
        // your code

        cached_function.apply(this, arguments); // use .apply() to call it

        // more of your code
    };
}());

Voici le violon: http://jsfiddle.net/kXkFS/


Notez que j'utilise .apply pour appeler la fonction de mise en cache. Cela me permet de conserver la valeur de this, et de transmettre ce que les arguments ont été transmis sous la forme d'arguments personnels, indépendamment de combien il y en avait.

32voto

ggreiner Points 5795

premier magasin de la fonction réelle d'une variable..

var oldFunction = someFunction;

ensuite, de définir votre propre:

someFunction = function(){
  // do something before
  oldFunction();
  // do something after
};

10voto

Rocket Hazmat Points 87407

Vous pouvez faire une fonction qui appelle votre code, puis appelle la fonction.

var old_someFunction = someFunction;
someFunction = function(){
    alert('Hello');
    old_someFunction();
    alert('Goodbye');
}

6voto

Ned Batchelder Points 128913

Je ne sais pas si vous pouvez mettre à jour la fonction, mais selon comment il est référencé, vous pouvez faire une nouvelle fonction à sa place:

var the_old_function = someFunction;
someFunction = function () {
    /* ..My new code... */
    the_old_function();
    /* ..More of my new code.. */
}

2voto

Luca Borrione Points 3038

Vous pouvez ou d'ajouter quelques nouveaux code d'une fonction existante juste de fusionner entre eux à l'aide par exemple:

function mergeFunctions(function1, function2, instance1, instance2, numberOfArgumentsToPassToFunc1) {
    return function() {
        var _arguments  = Array.prototype.slice.apply(arguments);
        var _arguments1 = _arguments.slice(0, numberOfArgumentsToPassToFunc1);
        var _arguments2 = _arguments.slice(numberOfArgumentsToPassToFunc1);
        var that = this;
        (function(function1, function2) {
            if (typeof function1 == "function") {
                if (typeof instance1 != "undefined") {
                    function1.apply(instance1, _arguments1);
                }
                else if (that == window) {
                    function1.apply(function1, _arguments1);
                }
                else {
                    var compare = mergeFunctions(function(){}, function(){});
                    if (that.toString() == compare.toString()) {
                        function1.apply(function1, _arguments1);
                    }
                    else {
                        function1.apply(that, _arguments1);
                    }
                }
            }
            if (typeof function2 == "function") {
                if (typeof instance2 != "undefined") {
                    function2.apply(instance2, _arguments2);
                }
                else if (that == window) {
                    function2.apply(function2, _arguments2);
                }
                else {
                    var compare = mergeFunctions(function(){}, function(){});
                    if (that.toString() == compare.toString()) {
                        function2.apply(function2, _arguments2);
                    }
                    else {
                        function2.apply(that, _arguments2);
                    }
                }
            }
        })(function1, function2);
    }
}



Donc dans votre exemple, c'est comme le suivant:

// Original function:
var someFunction = function(x){
    console.log("original content");
};

// Prepend new code:
// --------------------------------------------------------
someFunction = mergeFunctions(function(y) {
    console.log("--- prepended code");
}, someFunction);

// Testing:
someFunction();
console.log("");

// Outout:
// [Log] --- prepended code
// [Log] original content


// Append new code:
// --------------------------------------------------------
someFunction = mergeFunctions(someFunction, function() {
    console.log("appended code");
});

// Testing:
someFunction();

// Output:
// [Log] --- prepended code
// [Log] original content
// [Log] appended code



Notez que la fonction de fusion essaie d'appliquer les attend 'ce' pour la fusion de parties, sinon vous pouvez tout simplement passer le voulais " ce " pour eux, ainsi que vous pouvez gérer la relative arguments. Un exemple général est le suivant:

function firstPart(a, b) {
    console.log("--- first part");
    console.log("'this' here is:");
    console.log(this.name);
    console.log("a: "+a);
    console.log("b: "+b);
}

function MyObject() {
    this.x = "x property of MyObject";
}

MyObject.prototype.secondPart = function (y) {
    console.log("");
    console.log("--- second part");
    console.log("'this' here is:");
    console.log(this.name);
    this.x = y;
    console.log("x: "+this.x);
}

MyObject.prototype.merged = mergeFunctions(firstPart, MyObject.prototype.secondPart, firstPart, MyObject, 2);

// Testing
var test = new MyObject();
test.merged("a parameter", "b parameter", "x parameter overrides x property of MyObject");

// Console output:
// [Log] --- first part
// [Log] 'this' here is:
// [Log] firstPart
// [Log] a: a parameter
// [Log] b: b parameter
// [Log] 
// [Log] --- second part
// [Log] 'this' here is:
// [Log] MyObject
// [Log] x: x parameter overrides x property of MyObject

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X