Heim  >  Artikel  >  Web-Frontend  >  Die Verwendungen und Unterschiede zwischen „call“ und „apply“ in JavaScript

Die Verwendungen und Unterschiede zwischen „call“ und „apply“ in JavaScript

高洛峰
高洛峰Original
2017-01-12 11:31:131079Durchsuche

Apply akzeptiert zwei Parameter. Der zweite Parameter ist eine Sammlung mit Indizes. Die Apply-Methode konvertiert diese Sammlung into Die Elemente in werden als Parameter an die aufgerufene Funktion übergeben:

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

In diesem Code werden die Parameter 1, 2 und 3 im Array platziert und an die Funktion func übergeben Zusammen entsprechen sie a, b und c in der Funktionsparameterliste.

Die Anzahl der im Aufruf übergebenen Parameter ist nicht festgelegt. Ähnlich wie bei apply stellt der erste Parameter auch den This-Zeiger im Funktionskörper dar. Ab dem zweiten Parameter wird jeder Parameter der Reihe nach an die Funktion übergeben. :

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

Beim Aufruf einer Funktion berücksichtigt der JavaScript-Interpreter nicht den Unterschied in der Anzahl, Art und Reihenfolge der formalen Parameter und der tatsächlichen Parameter intern wird durch ein Array dargestellt. In diesem Sinne hat apply eine höhere Nutzungsrate als call. Es ist uns egal, wie viele Parameter an die Funktion übergeben werden, wir müssen nur apply verwenden, um sie alle zu pushen. call ist ein in apply verpackter syntaktischer Zucker. Wenn wir genau wissen, wie viele Parameter die Funktion akzeptiert, und die Entsprechung zwischen formalen Parametern und tatsächlichen Parametern auf einen Blick ausdrücken möchten, können wir call auch zum Übertragen von Parametern verwenden.

Verwendung von call und apply

1. Ändern Sie diesen Zeiger

Die häufigste Verwendung von call und apply besteht darin, diesen Zeiger innerhalb der Funktion zu ändern Beispiel:

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

Wenn der Code getName.call(obj1) ausgeführt wird, zeigt dies im getName-Funktionskörper auf das obj1-Objekt, also hier

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

entspricht tatsächlich:

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

In der tatsächlichen Entwicklung stoßen wir häufig auf Szenarien, in denen dieser Zeiger versehentlich geändert wird, z. B. ein Div-Knoten, ein Div Dies im Onclick-Ereignis des Knotens verweist ursprünglich auf dieses Div:

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

Wenn es eine interne Funktion func in der Ereignisfunktion gibt, wird die Funktion func innerhalb des Ereignisses aufgerufen Funktion „this“ im Hauptteil zeigt auf das Fenster, nicht auf das erwartete div. Siehe den folgenden Code:

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

Zu diesem Zeitpunkt verwenden wir call, um dies im zu ändern func-Funktion, damit sie auf div zeigt:

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

2. Function.prototype.bind

Die meisten fortgeschrittenen Browser implementieren die integrierte Function.prototype. bind zum Angeben dieser Punkte innerhalb der Funktion. Auch wenn es keine native Function.prototype.bind-Implementierung gibt, ist es für uns nicht schwierig, eine zu simulieren. Der Code lautet wie folgt:

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();

Wir verwenden Function.prototype.bind, um die Funktion func zu „umschließen“ und übergeben einen Objektkontext als Parameter. Dieses Kontextobjekt ist das Objekt, das wir ändern möchten.

In der internen Implementierung von Function.prototype.bind speichern wir zunächst den Verweis auf die Funktion func und geben dann eine neue Funktion zurück. Wenn wir die Funktion func in Zukunft ausführen, wird die gerade zurückgegebene neue Funktion tatsächlich zuerst ausgeführt. Innerhalb der neuen Funktion führt der Code self.apply(context, arguments) die ursprüngliche Funkfunktion aus und gibt das Kontextobjekt als this im Hauptteil der Funkfunktion an.

Dies ist eine vereinfachte Version der Function.prototype.bind-Implementierung.

ermöglicht es Ihnen, einige Parameter vorab in die Funktion func einzugeben:

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 );

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels jedem beim Lernen oder bei der Arbeit helfen kann.

Weitere Artikel über die Verwendung und Unterschiede von Call und Apply in JavaScript finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn