iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
Modern Web

超低腦容量學習法遇到javascript系列 第 8

有關這個(this)的二三事(下)

  • 分享至 

  • xImage
  •  

延續昨天的話題,今天舉了一些例子來說明實際上可能的應用場景。

解決simple function call的問題

如何避免呼叫一般函式時,其中的this是undefined的問題,最好的方法就是不要呼叫一般的函式,因為最好的進攻就是防守,解決問題不如解決提出問題的人但作為一個天天照三餐呼叫一般函式的程式小白,這境界好像離我有點遠。
我現在會作的是使用call() & bind()手動地指定this指向誰,下面舉兩個例子說明,一個是單純的simple function call,另一個是建構函式(constructor)串接,也就是一個建構函式要參照另一個建構函式時的作法。

第一個例子我們寫了一個含有this的一般函式

  • 直接呼叫的時候,因為this為undefined,所以無法讀取undefined的屬性,直接報錯了。這個結果其實蠻合理的,說真的實際上也應該不會這樣呼叫。
  • 如果使用call()去指定this為物件john,就可以調用物件內的屬性而算出年紀。
const calcAge = function () {
  return 2023 - this.birthYear;
};

const john = {
  firstName: "John",
  birthYear: 1990,
};

const age = calcAge(); //simple function call
console.log(age); //報錯, Cannot read properties of undefined (reading 'birthYear')

const age2 = calcAge.call(john); //use call() 指定this指向物件john 
console.log(age); //33

再來比較實際的使用是作在建構函式的互相參照,像下面的例子,Person是perant class,Student是想要參照Person的child class,我們如果直接在Student建構函式當中呼叫Person,因為把Person視為函式,這樣會變成simple function call,為了重新指定this,我們使用call()把Person裡的this,指向後來利用Student建立的新物件。

const Person = function (firstName, birthYear) {
  this.firstName = firstName;
  this.birthYear = birthYear;
};

const Student = function (firstName, birthYear, studying) {
  Person.call(this, firstName, birthYear);
  this.studying = studying;
};

const mark = new Person("Mark", 2000);
console.log(mark);

const peter = new Student("Peter", 2005, "Computer scinece");
console.log(peter);

何時用arrow function適合

在昨天的event listener的例子中,因為this指向監聽元素本身而造成bug,但若使用arrow function則可以輕巧簡單的避開這個問題。從執行結果可以發現,在event listener的calll back funct6ion改用arrow function之後,當中的this抓到的是外面一層也就是greet method的this:物件john。

const john = {
  firstName: "John",
  greet: function () {
    const btnEl = document.querySelector("button");
    btnEl.addEventListener("click", () => {
      console.log(this);
      alert(`Hi, I'm ${this.firstName}.`);
    });
  },
};

執行結果:

今日總結

熟悉this的幾個規則,就可以輕鬆面對各種this的應用變化,這跟本系列主題超低腦容量學習法根本超級切題的,我最喜歡這種了!


上一篇
有關這個(this)的二三事(上)
下一篇
js的模組化:Common js & ES module
系列文
超低腦容量學習法遇到javascript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言