在這里必須要提一句的是,this指向是學習js必須要掌握的(必須),再開始之前先看底部的總結,然后回上面看例子便一目了然。
例子1:
function a(){ var user = "TangSir"; console.log(this.user); //undefined console.log(this); //Window } a();
看總結第2條,這里函數本身沒有被父級對象調用,那么這里就指向window
function a(){ var user = "TangSir"; console.log(this.user); //undefined console.log(this); //Window } window.a();
可以發現是一樣的,這是因為window是全局對象,這里的a是被window點出來的,所以指向window(在這里也可以把window理解為a的父級,那么就是總結第3條)
例子2:
var o = { user:"TangSir", fn:function(){ console.log(this.user); //TangSir } } o.fn();
這里的this指向o(總結第3條)
var o = { user:"TangSir", fn:function(){ console.log(this.user); //TangSir } } window.o.fn();
這里加了個window,但是fn的父級還是o,是o調用了它(總結第3條)
var o = { a:12, b:{ a:14, fn:function(){ console.log(this.a); //14 } } } o.b.fn();
這里父級是b,那么this指向b(總結第3條)
例子3:
var o = { a:12, b:{ a:14, fn:function(){ console.log(this.a); //undefined console.log(this); //window } } } var j = o.b.fn; j();
這里為何是undefined而不是14?是誰最后調用了它,這里是j(),那么this只能是window(總結第1條)
例子4:
function Fn(){ this.user = "TangSir"; } var a = new Fn(); console.log(a.user); //TangSir
構造函數的this指向函數實例本身,這里賦給了a,等於賦值了一份給了a,那么a.user肯定也是TangSir(總結第5條)
例子5:
function Fn() { this.user = 'TangSir'; return {}; } var a = new Fn(); console.log(a.user); //undefined
因為返回的是對象,所以this指向該對象,所有是undefined(總結第6條)
function Fn() { this.user = 'TangSir'; return function(){}; } var a = new Fn(); console.log(a.user); //undefined
function同樣是對象,所以this指向該對象,所有是undefined(總結第6條)
function Fn() { this.user = 'TangSir'; return 1; } var a = new Fn(); console.log(a.user); //TangSir
這里this指向函數實例本身,所以是TangSir(總結第6條)
function Fn() { this.user = 'TangSir'; return undefined; } var a = new Fn(); console.log(a.user); //TangSir
這里this指向函數實例本身,所以是TangSir(總結第6條)
function Fn() { this.user = 'TangSir'; return null; } var a = new Fn(); console.log(a.user); //TangSir
函數里有null比較特殊,這里this指向函數實例本身,所以是TangSir(總結第6條)
例子6:
var obj = { name:"TangSir", fn:function(){
fn1=()=>{
console.log(this.name); //TangSir }
fn1(); } } obj.fn();
這里箭頭函數父級是fn,去掉父級后,fn1()此時的父級就是obj,那么this.name自然是TangSir(總結第6條和第3條)
例子7:
var o = { a:12, b:{ a:14, c:{
a:15,
d:function(){
console.log(this.a); //15
function e(){
console.log(this.a); //undefined
f();
}
e();
function f(){
console.log(this.a); //undefined
}
g=()=>{
console.log(this.a); //15
}
g();
}
} } } o.b.c.d();
這里第一個console是15(總結4),第二和第三個console是undefined,不然理解,它們的調用時f()和e(),所以是undefined,第三個是箭頭函數,根據例子6結合總結第7條,得出15
總結:
1、this在函數定義的時候是沒辦法確定指向的,只有函數執行的時候,最后誰調用了它才能確定this指向誰
2、如果函數中有this,但是函數本身沒有被父級(上一級)對象調用,那么就指向window
3、如果函數中有this,且函數本身被父級(上一級)對象調用,那么this就指向上一級對象
4、如果函數中有this,且函數中有多個對象,盡管函數被最外層對象調用,但this仍然指向父級(上一級)對象
5、構造函數中this,指向構造函數實例,如果創建的實例賦給對象,那么等於復制了一份給對象,該對象也擁有實例中的this(new出來的構造函數可以改變this指向)
6、構造函數中帶return,返回值若是對象,this指向的是那個返回的對象,返回值若是null,this還是指向那個構造函數實例
7、es6中=>箭頭函數中的this,去掉當前函數的父級(上一級)對象,再看this指向誰,此時指向誰就是誰(結合第3條)