Heim > Web-Frontend > js-Tutorial > Die Verwendungen und Unterschiede zwischen „call' und „apply' in JavaScript

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

高洛峰
Freigeben: 2017-01-12 11:31:13
Original
1108 Leute haben es durchsucht

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 ] );
Nach dem Login kopieren

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 );
Nach dem Login kopieren

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
Nach dem Login kopieren

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 );
};
Nach dem Login kopieren

entspricht tatsächlich:

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

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
};
Nach dem Login kopieren

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();
};
Nach dem Login kopieren

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 );
};
Nach dem Login kopieren

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();
Nach dem Login kopieren

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 );
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage