每一個函數都有它本身的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
的值等於undefined
:code
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)); //
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的過程到底發生了什麼:
this
指向事件發生的DOM元素:
<div> <button id="btn" onclick="alert(this)">alert</button> // 在彈出框中顯示:btn </div>
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>