js: this,call,apply,bind 總結


  對js中的一些基本的很重要的概念做一些總結,對進一步學習js很重。

一、this

  JavaScript 中的 this 總是指向一個對象,而具體指向那個對象是在運行時基於函數的執行環境動態綁定的,而非函數聲明時的環境
      實際應用中 this 的指向大致可以分為以下 4 中:
          1. 作為對象的方法調用
          2. 作為普通函數掉用
          3. 構造器調用
          4. Function.prototype.call 或 Function.prototype.apply 調用, 可以動態地改變出入函數的 this

  1. 作為對象的方法調用時, this 指向該對象

1 var obj = {
2     a: 1,
3     getA: function(){
4         console.log( this == obj ); // true
5         console.log( this.a ); // 1
6     }
7 };
8 obj.getA();

 

  2. 作為普通函數掉用,this 總是指向全局對象 window

1 console.log(this); // Windows
2 
3 window.name = "globalName";
4 var getName = function() {
5     return this.name;
6 }
7 
8 console.log( getName() ); // globalName

 

  3. 構造器調用, 當用 new 運算符調用函數時,該函數總是會返回一個對象,通常情況下,構造函數里的 this 就指向返回的這個對象

1 var MyClass = function(){
2     this.name = "class";    
3 }
4 var obj = new MyClass();
5 console.log( obj.name ); // class

 

  如果使用 new 調用構造器時,構造器顯式地返回了一個 object 類型的對象,那么此次運算結果最終會返回這個對象,而不是我么之前期待的 this

1 var MyClass = function(){
2     this.name = "class";
3     return {
4         name: "other"
5     }
6 }
7 var obj = new MyClass();
8 console.log(obj.name); // other

 

二、 call 和 apply

  他們的作用一模一樣,區別僅在於傳入參數形式的不同。
      apply 接收兩個參數,第一個參數指定了函數體內 this 對象的指向,第二個參數為一個帶下標的集合,這個集合可以是數組,也可以是類數組,apply 方法把這個集合中的元素作為參數傳入被調用的函數。
      call 傳入的參數不固定,跟 apply 相同的是,第一個參數也代表函數體內的 this 指向,從第二個參數開始往后,每個參數被依次傳入函數

1 var func = function(a, b, c){
2     console.log([a, b, c]);
3 }
4 //傳入的第一個參數為 null ,函數體內的 this 會指向默認的宿主對象,在瀏覽器中則是 window
5 func.apply(null, [1, 2, 3]); // 輸出:[ 1, 2, 3 ]
6 
7 func.call(null, 1, 2, 3); // 輸出:[ 1, 2, 3 ]

 

  call 和 apply 的用途:
      1. 改變 this 指向

 1 var obj1 = {
 2     name: "obj1"
 3 };
 4 var obj2 = {
 5     name: "obj2"
 6 };
 7 
 8 window.name = "window";
 9 
10 var getName = function(){
11     console.log( this.name );
12 }
13 
14 getName(); // window
15 getName.call( obj1 ); // obj1
16 getName.call( obj2 ); // obj2

 

  當執行 getName.call( obj1 ) 這句代碼時, getName 函數體內的 this 就指向 obj1 對象,所以此處的

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

 

    實際上相當於

var getName = function(){
    console.log( obj1.name );
}

 

  2. 用來模擬 Function.prototype.bind 指定函數內部的 this 指向
    
      3. 借用其他對象的方法, 可以模擬實現繼承

 1 var A = function(name){
 2     this.name = name;
 3 }
 4 var B = function(){
 5     A.apply( this, arguments);
 6 }
 7 B.prototype.getName = function(){
 8     return this.name;
 9 }
10 
11 var b = new B("2B鉛筆");
12 console.log( b.getName() ); // 輸出: 2B鉛筆

 

    借用 Array.prototype 對象上的方法,對參數列表 arguments 這個類數組對象,進行數組對象方法的調用

1 (function(){
2     Array.prototype.push.call( arguments, 3);
3     console.log( arguments ); // 輸出: [1, 2, 3]
4 })(1, 2);

 

三、ECMAScript 5 中的 bind() 方法可以將函數綁定到一個對象上  

1 function f(y) {return this.x + y};
2 var o = { x: 1};
3 var g = f.bind(o);
4 g(2); // 3

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM