iT邦幫忙

2023 iThome 鐵人賽

DAY 22
1

大家好,我是一名菜鳥工程師,Chris,今天來到第 22 天,JS 的 this 關鍵字

this:在 JavaScript 裡,一個特殊的關鍵字,它表示執行代碼的上下文,也是一個不固定的值

this的值在不同的情況,會有不同的意義

1. 誰呼叫,誰就是 this ; 哪個物件呼叫函式,函式內的 this 就會指向該物件

這裡的 this 會指向 obj 物件本身

let obj1 = {
  name: "Peter",
  age: 20,
  hi() {
    console.log(this);
  },
};


let obj2 = {
  name: "Jimmy",
  age: 34,
  hi() {
    console.log(this);
  },
};

obj1.hi(); // 印出 name 為 Peter 的物件

obj2.hi(); // 印出 name 為 Jimmy 的物件

2. 沒人呼叫,this 就是全域物件 ( window / global )

console.log(this); // 印出 window (全域物件)

3. 在函式中使用 this

  • 直接呼叫的函式,this 會指向全域
function globalFunction() {
  console.log(this); 
}

globalFunction(); // 印出 window
  • 對象方法:當函式作為對象的方法被調用時,this 會指向此函式的對象
const person = {
  name: "Leo",
  greet: function() {
    console.log(`Hello ${this.name}`);
  }
};

person.greet(); // 印出 Hello Leo
  • 建構式:this 會綁定在使用 new 關鍵字建立的實體物件
function Person(name) {
  this.name = name;
}

const alice = new Person("Alice");
console.log(alice.name); // 印出 Alice
function hi() {
        console.log(this);
      }

new hi(); // 使用 new,所以這裡的 this 指向空物件

4. 箭頭函式內的 this 會找離自己最近的範圍 (區域或全域) 作為綁定對象

箭頭函式沒有自己的 this,它會往外面找,通常會是全域物件

let abc = {
    name:"Tom",
    age:25,
    say: () => {
        console.log(this);
    }   
}

abc.say(); // 印出 window (全域物件)
obj = {
  name: "Jerry",
  update: function () {
    console.log(this.name);
    var setName = (updateName) => {
      this.name = updateName;
    };
    setName("Tiny");
    console.log(this.name); 
  },
};

obj.update();
// 印出 Jerry
// 印出 Tiny

5. 使用 callapplybind 方法

在 JS 裡,function 本身是物件,所以有一些方法可以用,例如 : callapplybind

  • callapply 方法
    • 使用 callapply 方法,可以將 this 強制變成自己想要的東西
    • callapply 類似,只是當使用 apply 方法時,其餘的參數需要用陣列包起來
    • callapply 方法的第 1 個值,會是 this
let obj = {
    name:"Cherry",
    age:30
}

function hi(a, b){
    console.log(this);
    console.log(a, b);
}

hi.call(obj, 1, 2);
hi.apply(obj, [3, 4]);
  • 為什麼需要 call、apply 方法來變更 this ?
    • 因為可以將 this 強制改為自己希望的物件
const hero = {
    hp : 100,
    mp : 10,
    attack : function(){
        console.log("ATTACK !!!");
    }
}

const mege = { 
    hp:50,
    mp:80,
    attack : function(){
        console.log("attack~~");
    },
    heal : function (){
        this.hp += 30;
    }
}
mege.heal();       // 這是原本 JS 的方法
console.log(mege); // 印出 {hp: 80, mp: 80, attack: ƒ, heal: ƒ}

mege.heal.call(hero); // 使用 call 方法,可將 this 強制改為 hero
console.log(hero);    // 印出 {hp: 130, mp: 10, attack: ƒ}
  • bind 方法
let obj = {
    name:"Cherry",
    age:30
}

function hi (a, b){
    console.log(a, b);
    console.log(this);
}

let newB = hi.bind(obj, 5, 6); // 沒有東西
newB(); //newB 變成新的 function,要呼叫它必須加()

// bind 方法會先將一部分綁定給它(新的 function),後續再作用

const newBIND = hi.bind(obj); // newBIND 會得到一個新的 function,將 this 變成 obj 傳進去

newBIND(5, 6); // 再把參數 5 和 6 傳進去
function multiple(a, b, c){
    return a * b * c ;
}

const ans = multiple.bind(null, 2); // 這裡的 null 為 this,因為用不到,所以設定為 null
console.log(ans(3, 4)); // 印出 24 (2*3*4)

6. 嚴格模式

在非嚴格模式下會回傳undefined;而在嚴格模式(strict)下會回報錯誤

嚴格模式有一個好處:避免不小心將 this 指向全域時,阻止我們更改到全域的東西

function hello(){
    "use strict"
    console.log(this);
}

hello(); // 印出 undefined

總結 : 以上就是關於 this 關鍵字的說明

今天就介紹到這邊,那我們明天見囉~~

明天預計內容:JS 的 閉包 (Closure)!!!


上一篇
DAY - 21 JS 的高階函式
下一篇
DAY 23 - Closure 閉包
系列文
前端開發 | 學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言