JavaScript this的5中應用場景

用一句話總結this的指向:this是在調用函數的時候,根據執行上下文所動態決定 。

應用場景一:當函數自然執行的時候,this是undefined或者window;例如

function myFunction() {
      console.log('this', this);
    }

myFunction()

//這種如果使用嚴格模式,則this是undefined

應用場景二:函數被別人調用的時 (被人誰 點.出來,this就是誰)

function myFunction() {
      console.log('this', this); //this是a對象
    }

    var a = {
      b: myFunction
    };
    a.b();

案例1:下面案例的this是指誰呢?

var father = {
      name: 'father',
      son: {
        name: 'son',
        buy: function () {
          console.log('this', this);
        }
      }
    };

    father.son.buy();

答案是son,函數前面有多少個點都不用管,只管裏執行時函數最近的那個點前面是誰,那麼this就是誰,當然,用apply/call/bind除外

案例2:

<script>
    var father = {
      name: 'father',
      buy: function () {
        console.log('this', this);
      }
    };

    var son = {
      name: 'son'
    }
    son.buy = father.buy;
    son.buy()// 這個時候this就是son
  </script>

案例3:

var father = {
      name: 'father',
      buy: function () {
        console.log('this', this);
      }
    };

    var son = {
      name: 'son'
    }
    son.buy = father.buy;
    var allbuy = son.buy;
    allbuy();

顯然上面的this是window,函數執行時;

案例4:

var father = {
      name: 'father',
      buy: function () {
        console.log('this', this);
      }
    };

    var son = {
      name: 'son'
    }
    son.buy = father.buy;
    // window.addEventListener('scroll', son.buy); // 這裏的this就是window,
    // 還有一個案例
    var a = (1,2); // 這裏涉及逗號表達式,這裏a的值是2,返回後一個值,
    (1, son.buy)(); // ==> var b = (1, son.buy); b() b執行,執行的時候,this是window

案例5:

function Person(params) {
      this.buy = function () {
        console.log('this', this);
      }
    }
    var xiaoming = new Person('xiaoming')
    var xiaohong = {};
    xiaohong.buy = xiaoming.buy;
    xiaohong.buy();// 這個時候,this就是xiaohong,看執行時是誰

應用場景三:new一個實例時

function Person(name) {
      this.name = name;
      console.log(this); // 使用new創建對象,這個時候this就是新創建的對象
    }
    var xiaoming = new Person('xiaoming');

應用場景四:apply、call、bind時

function getColor(params) {
      this.color = params;
      console.log(this);
    }

    function Car(name, color) {
      this.name = name;
      getColor(color).call(this);// 這裏把this把原來的變成了Car的shilling對象
    }

var lanbojini = new Car('lanbojini', 'black');

call和apply的區別,可以這樣記:call,打電話得一個一個打,apply可以一起打,或者“取長補短”

bind並非立即執行,bind不會改變原函數,它會返回來一個函數,返回來的這個函數執行,纔是用bind改變了this的函數

如果某個函數已經被bind過了,再次用.去調用,那麼規則2就不適用了:

var sonbuy = buy.bind(xiaoxiao);

father.sonbuy(); 這個時候,this任然是xiaoxiao,而不是father

應用場景五:箭頭函數的this指向由離箭頭函數最近的非箭頭函數的執行上下文決定(定義時)也就是:定義時離我最近的非箭頭函數的上下文是啥,我就是啥;

function outerWrap(params) {
      console.log('外層函數this', this);
      const outer = () => {
        console.log('outer this', this);
      }
      function innerCall() {
        console.log('innerCall', this);  // 這裏的this是window
        outer();
      }

      innerCall();
    }
    var wife = {
      name: 'wife'
    }
    wife.outer = outerWrap;
    wife.outer();

那麼箭頭函數認call和apply擺佈this嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章