函數上下文 this 判斷技巧。

在 JavaScript 的世界裏,一切均可以理解爲對象。包括函數,函數在 JS 中也是一類對象,不過是一類特殊的對象,將函數做爲構造類來使用,能夠生成新的對象,從而實現JS 世界中的類的概念。javascript

接下來咱們從頭開始回顧函數的發展過程。java

咱們知道,函數包含定義調用兩個階段,函數在使用以前,必須先定義。數組

函數定義

有的同窗可能更習慣用聲明來表示定義,不要緊,均可以。app

函數定義共分爲以下幾種:函數

  • 聲明式定義
  • 表達式定義
  • 構造函數式
  • 箭頭函數

接下來咱們一一介紹。ui

聲明式定義函數

最先咱們定義一個函數是這樣子的,也是最多見的。this

function test(){
    //todo
}
複製代碼

很簡單,定義好以後,咱們就可使用了:spa

test();
複製代碼

表達式定義函數

定義一個函數,也能夠理解爲定義一個變量,將這個變量的值指向一個函數,因而就有了另一種定義函數的方式(表達式定義):code

var test = function(){
    //todo
}
複製代碼

調用也很簡單對象

test();
複製代碼

那聲明式定義函數與表達式定義函數之間的區別是什麼? 你們看下面兩段代碼:

test();
function test(){
    //todo
}
複製代碼

對象方法的調用:

var a = {
    say:function(){
        //todo
    }
    
}
a.say();
複製代碼

函數調用時, 內部的this,必定是指向函數所屬的對象的。

構造函數式定義

var say = new Function('a','b','return a + b');
複製代碼

箭頭函數

ES6 規範中的函數定義方式。

let say = () => {};
複製代碼

函數調用

直接調用

let say = function(){console.log(this)}
say();
複製代碼

間接調用

間接調用分爲兩種,callapplycallapply 的做用就是改變函數調用的上下文。下面舉個例子來講明一下它們的做用。

咱們先定義一個函數 test:

function test(){
    console.log(this);
}
複製代碼

這個函數很簡單,僅僅是打印當前上下文 this。

咱們這樣調用

test();
複製代碼

輸出結果是 window。

我如今又有一個對象 a :

var a = {
    name: '小A'
}
複製代碼

我想讓a 對象執行 test 方法提供的功能,該怎麼辦呢?

固然,你們能夠說,我給 a 對象增長一個方法 testA,而後執行 a 對象的 testA 方法,不就能夠了嗎?

a.testA = function(){
    console.log(this);
}
a.testA();
複製代碼

那咱們若是不想爲 a 對象額外增長這個方法,而是複用最開始定義的 test 方法,怎麼辦?? 這就是 call 和 apply 的做用。

test.call(a);
//或者
test.apply(a);
複製代碼

這就是改變函數執行上下文的意思。

call 和 apply 的惟一區別是傳參不一樣。

call 的第一個參數是上下文對象,剩餘的參數就是函數調用時的參數。

test.call(a, 1, 2, 3);
複製代碼

apply 的第一個參數是上下文對象,第二個參數是個數組,數組中存放的是函數調用時的參數。

test.apply(a, [1, 2, 3]);
複製代碼

函數執行上下文 this 指向。

var a = {
    name: 'A',
    say: function(){
        console.log(this.name);
    }
}
a.say();
複製代碼

打印的是 'A'。

咱們接着看:

var a = {
    name: 'A',
    say: function(){
        function test(){
            console.log(this.name);
        }
        test();
    }
}
a.say();
複製代碼

執行結果是 undefined,而不是 'A'。 這是爲何?

一個簡單的理解方法:

一、凡是經過function 定義的函數裏面的 this 指向,必定是該函數調用時所指向的對象。

test() 等價爲 window.test()

因此 test() 執行時 this 指向 window。

二、箭頭函數裏面的 this 指向,必定是該箭頭函數在定義時所指向的執行上下文。

以上就是對函數 this 指向的一些概括,利用這些方法,能讓你精準地判斷 this 指向,即便寫一百層複雜嵌套函數,也能輕鬆判斷出來。

(本文完)

相關文章
相關標籤/搜索