this的五種指法

this 到底指向哪裏

如下若是沒說起,則爲嚴格模式。

js中做用域有兩種:python

  1. 詞法做用域
  2. 動態做用域

詞法做用域

詞法做用域指在書寫代碼時就被肯定的做用域。
看以下代碼babel

var value = 1;

    function foo() {
        console.log(value);
    }

    function bar() {
        var value = 2;
        foo();
    }

    bar();// 結果是1

動態做用域

動態做用域指在代碼運行時才被肯定的做用域。
js中只有this的做用域是動態做用域app

this的五種綁定

初學js時,會想固然認爲this遵循某一條規律,就像物理學那樣,然而並非。
this的綁定分爲五種狀況,這五種狀況之間毫無規律可言。不過好在都很簡單。框架

一. 默認綁定

當以以下形式執行一個函數時,this爲默認綁定;async

func()
  • 嚴格模式下,this爲undefined
  • 非嚴格模式下,this是全局對象。

與函數調用嵌套多少層如何嵌套無關函數

/* 全是undefined */
function printThis(){
    return this
}
var obj = {
    say(){
        console.log('obj.say',printThis())
    }
}
function funcB(){
    console.log('funcB',printThis());
    obj.say();
}
console.log('funcA',printThis())
obj.say()
funcB()

二. 隱式綁定

當以以下行駛執行一個函數時,this爲隱式綁定;工具

a.b.func()

此時this指向前面一個對象this

賦值會改變隱式綁定this的指向

  • 方法賦值給變量
class T {
    dotInvoke() {
        console.log('dotInvoke', this.sayThis())
    }
    sayThis() {
        return this
    }
    assignInvoke() {
        var sayThis = this.sayThis;
        console.log('assignInvoke', sayThis())
    }
}
var tt = new T();
tt.dotInvoke()// 指向T
tt.assignInvoke()// undefined
  • 函數被賦值成方法
function printThis(){
    return this
}
var obj = {};
obj.say = printThis;
obj.say()/* 指向obj */
  • 賦值給參數

極爲常見的是回調函數的this是undefined,由於回調函數被複制給參數,參數再調用時變成了默認綁定翻譯

function asyncFun(cb){
    cb()
}
var obj = {
    callback(){
        console.log(this)
    }
}
obj.callback()/*隱式綁定 obj */
asyncFun(obj.callback);/*默認綁定 undefined */

三. 箭頭函數

箭頭函數會讓this指向最近的函數或全局做用域code

  • 與最近的函數的this指向相同
function foo() {
        // 返回一個箭頭函數
        return (a)=>{
            //this 繼承自 foo()
            return this.a
        }
        ;
    }
    var obj1 = {
        a: 'obj1'
    };
    var obj2 = {
        a: 'obj2'
    }
    var arrow1 = foo.call(obj1);
    var arrow2 = foo.call(obj2);
    var arrow3 = foo();
    console.log('arrow1',arrow1())/* obj1 */
    console.log('arrow2',arrow2())/* obj2 */
    console.log('arrow3',arrow3())/* undefined,嚴格模式下報錯 */
  • 指向全局
var printThis = ()=>this;
console.log('printThis',printThis());/* global */
  • 指向實例
class Test {
    printThis = ()=>{
        return this
    }
}
//會被babel翻譯成
var test = function test() {
  var _this = this;

  this.printThis = function () {
    return _this;
  };
};

四. 顯示綁定

call, apply, bind指定this指向

五. new綁定

構造函數,ES6中的class
new構造函數,new class時,this指向實例

總結

  1. 五種綁定,後面兩種狀況單一,前面兩種會由於方法,函數被賦值而互相轉化。
  2. 由於this處於動態做用域,而目前開發時又大量使用框架。咱們寫下的代碼,並不老是由咱們本身調用,而是被打包工具打包後,由框架調用。致使咱們並不知道咱們寫下的函數和方法是否被框架複製過或顯示綁定過而改變了this指向。以致this指向更加撲朔迷離。
  3. 寫完本文頓時以爲,python裏指向明確的self完爆js的this。
相關文章
相關標籤/搜索