js中this的理解


關於this

  • this並不是指向函數本身。
  • this在任何情況下都不指向函數的詞法作用域。
  • this是在運行時進行綁定的,而並不是在編寫時綁定,它的上下文取決於函數調用時的各種條件。
  • this的綁定和函數聲明的位置沒有任何關系,只取決與函數的調用方法。

this的綁定規則

this到底綁定或者引用的是哪個對象環境決定於函數被調用的地方。而函數的調用有不同的方式,在不同的方式中調用決定this引用的是哪個對象是由四種規則確定的。

1、默認綁定

這條規則是最常見的,也是默認的。當函數被單獨定義和調用的時候,應用的規則就是綁定全局變量window(嚴格模式下是undefined)。即沒有其他綁定規則存在時的默認規則。

function fn() {
    console.log( this.a );
}
var a = 2;
fn(); // 2 -- fn單獨調用,this引用window

 

為什么說這里應用了默認綁定呢?

因為fn()是直接使用不帶任何修飾的函數引用進行調用的,因此只能使用默認綁定,無法應用其他規則。

2、隱式綁定

隱式調用的意思是,函數調用時擁有一個上下文對象,就好像這個函數是屬於該對象的一樣。必須在一個對象內部包含一個指向函數的屬性,並通過這個屬性間接引用函數,從而把this間接(隱式)綁定到這個對象上。

function fn() {
    console.log( this.a );
}
var obj = {
    a: 2,
    fn: fn
};
obj.fn(); // 2 -- this引用obj。

當函數引用有上下文對象時,隱式綁定規則會把函數調用中的this綁定到這個上下文對象。

需要說明的一點是,最后一個調用該函數的對象是傳到函數的上下文對象,對象屬性引用鏈中只有上一層或者說最后一層在調用位置中起作用,如下:

 function fn() {
     console.log( this.a );
 }
 var obj2 = {
     a: 42,
     fn: fn
 };
 var obj1 = {
     a: 2,
     obj2: obj2
 };
 obj1.obj2.fn(); // 42 -- this引用的是obj2.

如果一個函數中有this,這個函數中包含多個對象,盡管這個函數是被最外層的對象所調用,this指向的也只是它上一級的對象

隱式丟失問題:被隱式綁定的函數會丟失綁定對象,也就是說它會默認綁定,從而把this綁定到全局對象或undefined上,取決於是否是嚴格模式。如下:

 function fn() {
     console.log( this.a );
 }
 var obj = {
     a: 2,
     fn: fn
 };
 var bar = obj.fn; // 函數引用傳遞,只是函數的別名,而不是調用這個函數
 var a = "全局"; // 定義全局變量
 bar(); // "全局"

3、顯式綁定

使用bind()\apply()\call()函數:它接收的第一個參數即是上下文對象並將其賦給this

 function fn() {
     console.log( this.a );
 }
 var obj = {
     a: 2
 };
 fn.call( obj ); // 2

如果我們傳遞第一個值為簡單值,那么后台會自動轉換為對應的封裝對象。如果傳遞為null,那么結果就是在綁定默認全局變量,如:

 function fn() {
      console.log( this.a );
  }
  var obj = {
      a: 2
  };
 var a = 10;
 fn.call( null); // 10

4、new綁定

如果是一個構造函數,那么用new來調用,那么綁定的是新創建的對象,如下:

function fn(a) {
    this.a = a;
}
var bar = new fn( 2 );
console.log( bar.a );// 2

當this碰到return時

如下代碼:

function fn()  
{  
    this.user = '追夢子';  
    return {};  
}
var a = new fn;  
console.log(a.user); //undefined
function fn()  
{  
    this.user = '追夢子';  
    return function(){};
}
var a = new fn;  
console.log(a.user); //undefined

再如:

function fn()  
{  
    this.user = '追夢子';  
    return 1;
}
var a = new fn;  
console.log(a.user); //追夢子
function fn()  
{  
    this.user = '追夢子';  
    return undefined;
}
var a = new fn;  
console.log(a.user); //追夢子

總結:

  • 如果返回值是一個對象,那么this指向的就是那個返回的對象,如果返回值不是一個對象那么this還是指向函數的實例。
  • 還有一點就是雖然null也是對象,但是在這里this還是指向那個函數的實例,因為null比較特殊。
    function fn()  
    {  
        this.user = '追夢子';  
        return null;
    }
    var a = new fn;  
    console.log(a.user); //追夢子

 


免責聲明!

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



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