web-dev-qa-db-fra.com

La raison d'utiliser la méthode JS .call ()?

Je suis intéressé par la raison d'avoir la méthode call () dans JS. Il semble que cela duplique la méthode habituelle d'appeler this.

Par exemple, j'ai un code avec call ().

var obj = {
    objType: "Dog"
}

f = function(did_what, what) {
    alert(this.objType + " " + did_what + " " + what);
}

f.call(obj, "ate", "food");

La sortie est "Dog a mangé de la nourriture". Mais le même résultat, je peux obtenir l'attribution de la fonction à l'objet.

var obj = {
    objType: "Dog"
}

f = function(did_what, what) {
    alert(this.objType + " " + did_what + " " + what);
}

obj.a = f;
obj.a("ate", "food");

Le résultat est le même. Mais cette façon est plus compréhensible et plus pratique à utiliser. Pourquoi call () est nécessaire?

58
Green

call est utilisé lorsque vous souhaitez contrôler la portée qui sera utilisée dans la fonction appelée. Vous voudrez peut-être que le mot clé this soit autre chose que la portée à laquelle vous avez affecté la fonction, dans ces cas, vous pouvez utiliser call ou apply pour appeler la fonction avec la vôtre portée.

F.ex, il vous permet également d'appeler des méthodes utilitaires en dehors de la portée, comme lorsque vous utilisez des fonctions "privées":

var obj = (function() {
    var privateFn = function() {
        alert(this.id);
    }
    return {
        id: 123,
        publicFn: function() {
            privateFn.call(this);
        }
    };
}());

obj.publicFn();

Dans l'exemple ci-dessus, privateFn n'est pas exposé dans obj mais il peut toujours être construit comme s'il faisait partie de la portée publique (en utilisant this de la même manière) .

61
David Hellsing

mise à jour 2017

Toutes les fonctions via Function.prototype ont la méthode .call. La raison d'utiliser .call() est de spécifier à quoi fait référence la variable "this".

MDN spécifie:

La méthode call() appelle une fonction avec une valeur donnée et des arguments fournis individuellement.

Considérer ce qui suit:

function x() {
    return this;
}

x()

En mode strict x() renvoie undefined en mode non strict, il renvoie l'objet Global, Window dans un contexte de navigateur.

Exemple avec .call() on lui dit à quoi "this" fait référence:

function x() {
    return this;
}

var obj = {
    myName      : 'Robert',
    myLocation  : 'Earth'
}

x.call(obj);

Résultat: {myName: "Robert", myLocation: "Earth"}. Dans l'exemple ci-dessus, nous spécifions l'objet obj comme valeur de this à l'intérieur de la fonction x()

Il peut être utilisé pour émuler l'héritage dans la POO.

Exemple:

var Robert = {
    name: "Robert Rocha",
    age: 12,
    height: "5,1",
    sex: "male",
    describe: function() {
        return "This is me " + this.name + " " + this.age + " " + this.height + " " + this.sex;
    }
};

Disons que ce qui précède est un objet maître (prototype) et que vous souhaitez hériter de la fonction describe dans un autre objet:

var Richard = {
    name: "Richard Sash",
    age: 25,
    height: "6,4",
    sex: "male",
}

L'objet Richard n'a pas la fonction de description et vous voulez simplement hériter, pour ainsi dire, de la fonction. Vous le feriez comme ça:

console.log( Robert.describe.call( Richard ) );

Sortie: This is me Richard Sash 25 6,4 male

39
Robert Rocha

Vous utiliseriez probablement la deuxième manière dans votre exemple, mais parfois vous voulez utiliser les fonctions d'un objet sur un autre objet. Un exemple serait d'utiliser des méthodes Array sur des objets de type tableau comme NodeLists

var el = document.getElementById("foo");
[].forEach.call(el.children, function(child, index) {
    //Iterate over an element's children, performing an action on each one
});
6
Dennis

C'est à voir avec le concept d'une fonction de première classe . Fondamentalement, des langages comme Javascript vous permettent de traiter les fonctions comme des choses à part entière. Les fonctions peuvent être stockées dans des variables ou transmises à d'autres fonctions.

call() fournit un moyen d'exécuter une fonction autonome non attachée à aucun autre objet.

3
Rob Agar