JavaScript:this的指向

理解JS中this的指向

每一個函數都有它本身的this值,在絕大多數狀況下,this指向調用了函數的那個對象。
爲了本身更加清楚地認識this的指向,我總結出瞭如下幾種狀況:app

全局環境中的this

不管是否處於嚴格模式,在全局環境中(或者理解爲在任何函數體的外部)this 都指代全局對象:函數

console.log(this); //全局對象

var num = 100;
console.log(this.num); // 100

函數內部中的this

在全局環境中調用函數,函數內部的this指向有如下兩種狀況:this

在非嚴格模式下,this的值等於全局對象:指針

function temp(){
    return this;
};
console.log(temp()); //全局對象

在嚴格模式下,因爲this並無被提早定義,因此,this的值等於undefinedcode

function temp(){
    "use strict";
    return this;
};
console.log(temp()); //undefined

用apply和call方法能夠指定this的值:對象

var obj = {
    name: 'Tom'
};

function temp(){
    "use strict";
    return this;
};

console.log(temp.call(obj)); //{name: "Tom"}

補充知識點:在嚴格模式下,經過this傳遞給一個函數的值不會被強制轉換爲一個對象:繼承

function temp(){
    "use strict"; 
    return this
}
console.log(temp.call(true)); // true
console.log(temp.call(56)); // 56
console.log(temp.apply(null)); //

ES6箭頭函數中的this

箭頭函數不會建立本身的this,它只會從本身所處的做用域鏈的上一層繼承this事件

例1:箭頭函數沒有本身的this指針,經過call或apply方法調用一個箭頭函數時,爲this綁定特定的值是無效的:ip

var name = 'window';

var obj = {
    name: 'Tom'
};

var temp = () => {
    return this.name;
};

console.log(temp.call(obj)); //window

箭頭函數是在全局環境中調用的,它上一層的this指向全局對象,因此,它的this也指向全局對象。作用域

例2:在函數內部建立的箭頭函數,其this指向等同於包含函數的this指向:

name = 'window';

let obj = {
    name: 'Tom',
    test: function(){
        let temp = (()=>{
          return this.name;
        });
        return temp;
    }
};

console.log(obj.test()()); //Tom

包含函數做爲對象裏面的方法被調用時,它的this指向調用它的對象obj,因此,箭頭函數的this也指向obj。

name = 'window';

let obj = {
    name: 'Tom',
    test: function(){
        let temp = (()=>{
          return this.name;
        });
        return temp;
    }
};

let a = obj.test;
console.log(a()()); //window

包含函數被賦值給一個全局變量,以後再在全局環境中調用,顯然,此時它的this指向調用它的全局對象,因此,箭頭函數的this也指向全局對象。

例3:明白了箭頭函數的this指向原理,在回調函數中就不用寫這樣的代碼了:var that = this,這裏以setTimeout的回調函數爲例:

不用箭頭函數:

var name = "outer";

var obj = {
    name: 'Tom'
};

function temp(){
    let that = this;
    setTimeout(function(){
        console.log(that.name);
    },1000);
}

temp.call(obj); //Tom

使用箭頭函數:

var name = "outer";

var obj = {
    name: 'Tom'
};

function temp(){
    setTimeout(() => {
        console.log(this.name);
    },1000);
}

temp.call(obj); // Tom

做爲對象的方法中的this

對象中函數的this指向調用函數的那個對象, 而且是離得最近的那個對象:

name = 'window';

let obj1 = {
    name: '1',
    test: function(){
        return this.name;
    },
    other: {
        name: '2'
    }
};

obj1.other.test = obj1.test;

console.log(obj1.test()); // 1
console.log(obj1.other.test()); //2

let aa = obj1.test;
console.log(aa()); //全局對象

構造函數中的this

構造函數中的this指向建立的新對象:

function Person(name){
    this.name = name;
};
let child = new Person('Tom');

補充知識點:new的過程到底發生了什麼:

  1. 建立一個新的對象child;
  2. 將構造函數的做用域賦給對象,即構造函數中的this指向child;
  3. 執行構造函數中的操做;
  4. 返回對象child({name: "Tom"})。

內聯函數中的this

指向事件發生的DOM元素:

<div>    
    <button id="btn" onclick="alert(this)">alert</button> // 在彈出框中顯示:btn
</div>

Dom事件處理函數中的this

當一個函數被用做事件處理函數時,它的this指向觸發事件的元素:

<div>    
    <input type="button" id="btn" value="Click Me"/>
</div>
<script>
    var btn = document.getElementById('btn');
    btn.addEventListener('click', function(){
        console.log(this.id); // btn
    }, false);
</script>
相關文章
相關標籤/搜索