js中的this是個很妙的東西,你經常不知道它到底在指向誰,又是誰在調用它。
通用判斷方法:
1.this總是指向它的直接調用者
var a={ user:'Artimis', fn:function(){ console.log(this.user) } } a.fn() //Artimis => this指向a var b=a.fn; b() //undefined => this指向window
2.如果沒有找到直接調用者,則this指向window
function fn(){ var user='Artimis'; console.log(this.user) } fn() //undefined => this指向window
3.遇到return,如果返回的是對象,則this指向返回對象,否則指向函數實例
function A(){ this.user='Artimis'; return {} //return一個空對象 } var a=new A(); console.log(a.user) //undefined => this指向return的{} function B(){ this.user='Artimis'; return 1 //return一個數值 } var b=new B(); console.log(b.user) //Artimis => this指向b
4.使用call/apply/bind綁定的,this指向綁定對象
5.定時器(匿名函數)內沒有默認的宿主對象,所以this指向window
6.箭頭函數內部沒有this,this指向外層最近的調用者
1> 箭頭函數在調用時,不會生成自身作用域下的this和arguments
2> 不像普通函數一樣在調用時自動獲取this,而是沿着作用域鏈向上查找,找到最近的外部一層作用域的this,並獲取
3> 在定義對象的方法/具有動態上下文的回調函數/構造函數中都不適用
改變this指針指向:
1.new操作符
new會創造一個對象實例,這個實例繼承了new操作符右邊的對象,因此在調用方法時,this會指向對象實例
function A(){ this.user='Artimis' } var a=new A(); console.log(a.user) //Artimis => this指向a
2.call/apply/bind
call和apply主要用於指定this的環境變量,第一個參數是什么,this就指向什么,如果是null,則指向window
var a={ user:'Artimis', fn:function(){ console.log(this.user) } } var b=a.fn;
b() //undefined b.call(a) //Artimis => this指向a b.call(null) //undefined => this指向window
bind是延遲的,會返回一個修改后的函數,可以自行決定執行的時間
var a={ user:'Artimis', fn:function(){ console.log(this.user) } } var b=a.fn; var c=b.bind(a) c() //Artimis => 延遲執行,自定義執行時間
var a={ fn:function(x,y){ console.log(x+y) } } var b=a.fn; var c=b.bind(a,2) //自定義參數x c(3) //5