1. 程式人生 > 實用技巧 >徹底搞懂js this指向問題

徹底搞懂js this指向問題

在這裡必須要提一句的是,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條)