Maison  >  Article  >  interface Web  >  Les utilisations et les différences entre call et apply en JavaScript

Les utilisations et les différences entre call et apply en JavaScript

高洛峰
高洛峰original
2017-01-12 11:31:131077parcourir

apply accepte deux paramètres. Le premier paramètre spécifie le pointeur de cet objet dans le corps de la fonction. Le deuxième paramètre est une collection avec des indices. Cette collection peut être un tableau ou un tableau de type tableau. into Les éléments dans sont passés en paramètres à la fonction appelée :

var func = function( a, b, c ){
  alert ( [ a, b, c ] ); // 输出 [ 1, 2, 3 ]
};
func.apply( null, [ 1, 2, 3 ] );

Dans ce code, les paramètres 1, 2 et 3 sont placés dans le tableau et passés dans la fonction func ensemble, ils correspondent respectivement à a, b et c dans la liste des paramètres func.

Le nombre de paramètres passés lors de l'appel n'est pas fixe. De la même manière, le premier paramètre représente également le pointeur this dans le corps de la fonction. À partir du deuxième paramètre, chaque paramètre est passé tour à tour dans la fonction. :

var func = function( a, b, c ){
  alert ( [ a, b, c ] ); // 输出 [ 1, 2, 3 ]
};
func.call( null, 1, 2, 3 );

Lors de l'appel d'une fonction, l'interpréteur JavaScript ne tient pas compte de la différence dans le nombre, le type et l'ordre des paramètres formels et des paramètres JavaScript réels. est représenté par un tableau. En ce sens, apply a un taux d'utilisation plus élevé que call. Nous n'avons pas à nous soucier du nombre de paramètres transmis à la fonction, il nous suffit d'utiliser apply pour les pousser tous. call est un sucre syntaxique enveloppé dans apply. Si nous savons exactement combien de paramètres la fonction accepte et que nous voulons exprimer en un coup d'œil la correspondance entre les paramètres formels et les paramètres réels, nous pouvons également utiliser call pour transférer des paramètres.

Utilisations de call et apply

1. Changer ce pointeur

L'utilisation la plus courante de call et apply consiste à modifier le pointeur this à l'intérieur de la fonction. exemple :

var obj1 = {
  name: 'sven'
};
var obj2 = {
  name: 'anne'
};
window.name = 'window';
var getName = function(){
  alert ( this.name );
};
getName(); // 输出: window
getName.call( obj1 ); // 输出: sven
getName.call( obj2 ); // 输出: anne

Lorsque le code getName.call(obj1) est exécuté, ceci dans le corps de la fonction getName pointe vers l'objet obj1, donc ici

var getName = function(){
alert ( this.name );
};

est en fait équivalent à :

var getName = function(){
alert ( obj1.name ); // 输出: sven
};

Dans le développement réel, nous rencontrons souvent des scénarios où ce pointeur est modifié par inadvertance, comme un nœud div, div Ceci dans l'événement onclick du nœud pointe à l'origine vers ce div :

document.getElementById( 'div1' ).onclick = function(){
  alert( this.id ); // 输出:div1
};

S'il existe une fonction interne func dans la fonction événement, lorsque la fonction func est appelée à l'intérieur de l'événement, le func function Le this dans le corps pointe vers la fenêtre, pas le div auquel nous nous attendions. Voir le code suivant :

document.getElementById( 'div1' ).onclick = function(){
  alert( this.id ); // 输出:div1
  var func = function(){
    alert ( this.id ); // 输出:undefined
  }
  func();
};

À ce stade, nous utilisons call pour modifier this dans le. func pour qu'il reste Pointer vers div :

document.getElementById( 'div1' ).onclick = function(){
  var func = function(){
    alert ( this.id ); // 输出:div1
  }
  func.call( this );
};

2. Function.prototype.bind

La plupart des navigateurs avancés implémentent le Function.prototype intégré. bind pour spécifier les points This à l'intérieur de la fonction. Même s'il n'y a pas d'implémentation native de Function.prototype.bind, il ne nous est pas difficile d'en simuler une. Le code est le suivant :

Function.prototype.bind = function( context ){
var self = this; // 保存原函数
return function(){ // 返回一个新的函数
    return self.apply( context, arguments ); // 执行新的函数的时候,会   把之前传入的context
  // 当作新函数体内的this
  }
};
var obj = {
  name: 'sven'
};
var func = function(){
  alert ( this.name ); // 输出:sven
}.bind( obj);
func();

.

Nous utilisons Function.prototype.bind pour "envelopper" la fonction func et la transmettre dans un contexte d'objet en tant que paramètre. Cet objet de contexte est l'objet this que nous voulons modifier.

Dans l'implémentation interne de Function.prototype.bind, nous enregistrons d'abord la référence à la fonction func, puis renvoyons une nouvelle fonction. Lorsque nous exécuterons la fonction func à l'avenir, la nouvelle fonction qui vient de revenir est en fait exécutée en premier. À l'intérieur de la nouvelle fonction, le code self.apply(context, arguments) exécute la fonction func d'origine et spécifie l'objet contextuel comme ceci dans le corps de la fonction func.

Il s'agit d'une version simplifiée de l'implémentation de Function.prototype.bind. Habituellement, nous l'implémenterons un peu plus compliquément

vous permet de pré-remplir certains paramètres dans la fonction func :

Function.prototype.bind = function(){
  var self = this, // 保存原函数
  context = [].shift.call( arguments ), // 需要绑定的this 上下文
  args = [].slice.call( arguments ); // 剩余的参数转成数组
  return function(){ // 返回一个新的函数
    return self.apply( context, [].concat.call( args, [].slice.call(  arguments ) ) );
    // 执行新的函数的时候,会把之前传入的context 当作新函数体内的this
    // 并且组合两次分别传入的参数,作为新函数的参数
  }
};
var obj = {
  name: 'sven'
};
var func = function( a, b, c, d ){
  alert ( this.name ); // 输出:sven
  alert ( [ a, b, c, d ] ) // 输出:[ 1, 2, 3, 4 ]
}.bind( obj, 1, 2 );
func( 3, 4 );

Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article pourra apporter de l'aide à l'étude ou au travail de chacun. J'espère également soutenir le site Web PHP chinois !

Pour plus d'articles sur les utilisations et les différences de call and apply en JavaScript, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn