JavaScript 系列之 this(二)

這是我參與8月更文挑戰的第12天,活動詳情查看:8月更文挑戰javascript

2、改變 this 的指向

var name = "windowsName";
var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    setTimeout(function () {
      this.func1();
    }, 100);
  },
};
a.func2(); // this.func1 is not a function
複製代碼

在不使用箭頭函數的狀況下,是會報錯的,由於最後調用 setTimeout 的對象是 window,可是在 window 中並無 func1 函數。前端

2.1 使用 ES6 的箭頭函數

箭頭函數中沒有 this 綁定,必須經過查找做用域鏈來決定其值,若是箭頭函數被非箭頭函數包含,則 this 綁定的是最近一層非箭頭函數的 this,不然,this 爲 undefined。java

var name = "windowsName";
var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    setTimeout(() => {
      this.func1();
    }, 100);
  },
};
a.func2(); // Cherry
複製代碼

2.2 在函數內部使用 _this = this

若是不使用 ES6,那麼這種方式應該是最簡單的不會出錯的方式了,咱們是先將調用這個函數的對象保存在變量 _this 中,而後在函數中使用這個 _this,這樣 _this 就不會改變了。react

var name = "windowsName";
var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    var _this = this;
    setTimeout(function () {
      _this.func1();
    }, 100);
  },
};
a.func2(); // Cherry
複製代碼

這個例子中,在 func2 中,首先設置 var _this = this;,這裏的 this 是調用 func2 的對象 a,爲了防止在 func2 中的 setTimeout 被 window 調用而致使的在 setTimeout 中的 this 爲 window。咱們將 this(指向變量 a) 賦值給一個變量 _this,這樣,在 func2 中咱們使用 _this 就是指向對象 a 了。面試

2.3 使用 call、apply、bind

一、使用 callwindows

var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    setTimeout(
      function () {
        this.func1();
      }.call(a),
      100
    );
  },
};
a.func2(); // Cherry
複製代碼

二、使用 apply數組

var a = {
  name: "Cherry",
  
  func1: function () {
    console.log(this.name);
  },
  
  func2: function () {
    setTimeout(
      function () {
        this.func1();
      }.apply(a),
      100
    );
  },
};
a.func2(); // Cherry
複製代碼

三、使用 bind性能優化

var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },
  
  func2: function () {
    setTimeout(
      function () {
        this.func1();
      }.bind(a)(),
      100
    );
  },
};
a.func2(); // Cherry
複製代碼

2.4 new 實例化一個對象

3、對 call 和 apply 和 bind 分析

3.1 call 和 apply 的區別

call 和 apply 都是爲了解決改變 this 的指向。做用都是相同的,只是傳參的方式不一樣。markdown

除了第一個參數外,call 能夠接收一個參數列表,apply 只接受一個參數數組。app

在 fun 函數運行時指定的 this 值:

  • fun.call(thisArg, arg1, arg2, ...)
  • func.apply(thisArg, [argsArray])
var a = {
  value: 1,
};
function getValue(name, age) {
  console.log(name);
  console.log(age);
  console.log(this.value);
}
getValue.call(a, "yck", "24"); // yck 24 1
getValue.apply(a, ["yck", "24"]); // yck 24 1
複製代碼

3.2 bind

bind() 方法建立一個新的函數, 當被調用時,將其 this 關鍵字設置爲提供的值,在調用新函數時,在任何提供以前提供一個給定的參數序列。

var a = {
  name: "Cherry",
  fn: function (a, b) {
    console.log(a + b);
  },
};
var b = a.fn;
b.bind(a, 1, 2)(); // 3
複製代碼

相關文章

相關文章
相關標籤/搜索