哪裏調用this就指向哪裏。this指向依賴於調用時的位置和調用方法,而非建立時的位置。
默認狀況下,全局上下文環境的this指向於window對象。git
var a = 1; console.log(this.a); // 1 console.log(this == window); // true
值得注意的是,在ES6中let關鍵字聲明定義的全局變量,不掛在頂層對象window中github
let a = 1; console.log(this.a); // undefined console.log(this == window); // true
在分析函數上下文以前,咱們先來了解下調用位置。JavaScript引擎在執行代碼時按照順序執行,則全局上下文(global text)應當首先進入調用棧。以後纔是函數上下文進棧,當函數被調用時則進行出棧。數組
舉個例子app
function foo(){ foo2(); } function foo2(){ foo3(); } function foo3(){ console.log("i am foo3"); } foo();
如上這段代碼,最開始是全局上下文首先入棧,然後foo入棧,看到foo中還調用foo2則繼續進棧,同理入棧foo3。根據棧後進先出的原則,則foo3首先被彈出棧,然後foo二、foo依次出棧。該函數上下文所在棧元素的前一個元素,則爲調用位置。而實際上,須要結合調用方式來斷定。函數
var a = 1; function foo(){ var a = 2; foo2(); } function foo2(){ var a = 3; console.log(this.a); // 1 foo3(); } function foo3(){ console.log(this.a); // 1 console.log("i am foo3"); } foo();
此處爲函數獨立調用,因此this實際指向於windowthis
在非嚴格模式下,普通函數的this指向於windowcode
var a = 1; function foo(){ console.log(this.a); }
而在嚴格模式下,普通函數的this是undefined對象
'use strict' var a = 1; function foo(){ console.log(this); // undefined console.log(this.a); // 報錯 } foo();
嵌套函數調用事件
var a = 1; function foo(){ return function(){ var a = 2; console.log(this.a); } } foo()(); // 1 var f = foo(); f(); // 1
在一個函數上下文中,this由調用者提供,由調用函數的方式來決定。若是調用者函數,被某一個對象所擁有,那麼該函數在調用時,內部的this指向該對象。ip
var a = 1; function getA(){ return this.a; } var obj = { a:2, foo:getA } console.log(obj.foo()); // 2
若是函數獨立調用,那麼該函數內部的this,則指向undefined。可是在非嚴格模式中,當this指向undefined時,它會被自動指向全局對象。
var a = 1; function getA(){ return this.a; } var obj = { a:2, foo:getA }; var f = obj.foo; console.log(f()); // 1
須要注意的是,這僅是針對函數上下文而言。
var a = 1; function getA(){ return this.a; } var obj = { a:2, b:this.a, foo:function(){ return this.a; } }; console.log(obj.b); // 1 console.log(obj.foo()); // 2
使用call/apply調用時,this做用域指向call/apply的第一個參數對象。call/apply自己差異不大,主要差異就是call傳遞的形參是一個一個的,而apply是一整個數組傳。
var song = 'hello'; function sing(){ console.log(this.song); } var obj = { song:'let it go' }; sing.call(obj); // let it go
this指向被建立的對象
var age = 13; function Animal(age){ this.age = age; } var dog = new Animal(12); console.log(dog.age); //12
this指向於觸發事件的DOM元素
var ele = document.getElementById("id"); ele.addEventListener("click",function(e){ console.log(this); console.log(this === e.target); // true })
箭頭函數調用應當是this指向在函數調用裏面的特例了,在箭頭函數中,會捕獲其所在上下文的this值,做爲本身的this值。簡單來講,就是包裹箭頭函數的第一個普通函數中的this。
function foo() { setTimeout(()=>{ console.log(this.a); },100) } var obj = { a: 2 } foo.call(obj); // 2
肯定This指向時,首先找到函數調用位置及調用方式
new
調用:綁定到新建立的對象call
或apply
、bind
調用:綁定到指定的對象參考文章: https://github.com/axuebin/ar...