DEV Community

SGsSY
SGsSY

Posted on

The Most Familiar Stranger - JavaScript - 函式

分享記錄檔 YouTube

函式

JavaScript 中的函式是一種可重複使用的程式碼,它可以接受參數並執行特定的任務。函式可以在程式中多次呼叫,這樣可以使程式更為彈性,更容易維護。

如何宣告函式

在 JavaScript 中,可以使用function 關鍵字來宣告一個函式。

以下是一個簡單的函式宣告範例:

function add(a, b) {
  return a + b;
}
Enter fullscreen mode Exit fullscreen mode

在此範例中,add 函式接受兩個參數,並將它們相加後返回結果。函式可以被呼叫多次,並且每次呼叫時可以傳入不同的參數值。

記憶體的變化

當函式被呼叫時,JavaScript 引擎會為該函式創建一個新的執行上下文 ( Execution Context )。該執行上下文包含函式中聲明的所有變數、參數和函式本身。當函式執行完畢並返回結果時,該執行上下文將被釋放,所有在該函式中聲明的變數和參數也將被清除。

執行上下文 ( Execution Context )

在 JavaScript 中,每當執行一個函式時,JavaScript 引擎都會創建一個新的執行上下文。

JavaScript 中的執行上下文是一種無名物件,它包含了以下三個屬性:

  1. Variable Object ( 變數物件 ): 儲存該執行上下文中所宣告的變數、函式和參數等。
  2. Scope Chain ( 作用域鏈 ): 它是用來尋找變數和函式定義的一個層層包含的列表。作用域鏈在函式被定義時就已經確定了。
  3. this : 它指向當前執行上下文所屬的物件。

當 JavaScript 引擎執行一段程式碼時,它會創建一個全域執行上下文 ( Global Execution Context )。在瀏覽器中,全域執行上下文通常關聯到 Window 物件。接下來,每當 JavaScript 引擎執行一個函式時,它會創建一個新的執行上下文。

以下是一個簡單的範例,說明了執行上下文如何運作:

var x = 1;

function add(y) {
  var result = x + y;
  return result;
}

console.log(add(2)); // 3

Enter fullscreen mode Exit fullscreen mode

在此範例中,當 add 函式被呼叫時,JavaScript 引擎會創建一個新的執行上下文,其中包含了變數 yresult。此外,由於 add 函式是在全域範圍內被定義的,因此它的作用域鏈會包含全域作用域鏈。

add 函式執行完畢並返回結果時,JavaScript 引擎會釋放該執行上下文,並將該函式的結果返回到 Call stack 中。

Call stack

JavaScript 中的呼叫堆疊(call stack)是一種用於追蹤函式執行的機制。當函式被呼叫時,它會被添加到呼叫堆疊的頂部。當函式執行完畢並返回結果時,它將從堆疊中彈出,讓下一個函式繼續執行。JavaScript 引擎使用呼叫堆疊來確保函式執行的順序和一致性。

以下是一個簡單的例子,說明了呼叫堆疊如何運作:

function fn1() {
  console.log("a");
}

function fn2() {
  fn1();
}

function fn3() {
  fn2();
}

fn3();

Enter fullscreen mode Exit fullscreen mode

在此範例中,當 fn3 函式被呼叫時,它會被添加到呼叫堆疊的頂部。當 fn3 函式調用 fn2 函式時, fn2 函式被添加到堆疊的頂部。當 fn2 函式調用 fn1 函式時, fn1 函式被添加到堆疊的頂部。當 fn1 函式執行完畢時,它從堆疊中彈出,讓 fn2 函式繼續執行。當 fn2 函式執行完畢時,它從堆疊中彈出,讓 fn3 函式繼續執行。最後,當 fn3 函式執行完畢時,它從堆疊中彈出,函式呼叫堆疊就空了。

以下是一個動畫,說明了呼叫堆疊如何運作:

圖片來源:[https://vaibhavgupta.me/2018/01/20/understanding-event-loop/](https://vaibhavgupta.me/2018/01/20/understanding-event-loop/)

圖片來源:https://vaibhavgupta.me/2018/01/20/understanding-event-loop/

this 是什麼

在 JavaScript 中,this 關鍵字用於引用當前執行上下文中的物件。this 關鍵字的值取決於函式的調用方式,它可以是全域物件、函式本身或由該函式創建的新物件。

當在全域範圍內使用 this *時,它會指向全域物件 (在瀏覽器中是 Window *)。

以下是一個範例:

console.log(this); // Window
Enter fullscreen mode Exit fullscreen mode

以下是一個簡單的範例,其中 this 關鍵字用於引用當前執行上下文中的物件:

const person = {
  firstName: 'John',
  lastName: 'Doe',
  fullName: function() {
    return `${this.firstName} ${this.lastName}`;
  }
}

console.log(person.fullName()); // "John Doe"
Enter fullscreen mode Exit fullscreen mode

在此範例中,this 關鍵字用於引用 person 物件,因為函式是在 person 物件上調用的。

🔑 一般的函式呼叫 JS 會預設將 this 綁定到全域物件,當從某個物件的參考屬性呼叫 this 會綁定到該物件

let obj = {
    function1: function() {
        console.log(this); // obj

        let function2 = function() {
            console.log(this); // Window
        }
        function2();
    }
};
obj.function1();
Enter fullscreen mode Exit fullscreen mode

當使用 call()apply() ****或 bind() 方法時,可以手動指定 this 的值。

以下是一個範例:

const person1 = {
  firstName: 'John',
  lastName: 'Doe'
}

const person2 = {
  firstName: 'Jane',
  lastName: 'Don'
}

function fullName() {
  return `${this.firstName} ${this.lastName}`;
}

console.log(fullName.call(person1)); // "John Doe"
console.log(fullName.call(person2)); // "Jane Don"
Enter fullscreen mode Exit fullscreen mode

💡 call()apply()bind() 的不同

  1. call()apply() 會立即執行函式,bind() 會回傳一個新的函式
  2. call(thisArg[, arg1[, ...]]) ****是列出所有參數,apply(thisArg, [argsArray]) 是傳入陣列

在使用 new *關鍵字創建一個物件時,this *會指向這個新物件。

以下是一個範例:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.fullName = function() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const john = new Person('John', 'Doe');
console.log(john.fullName()); // "John Doe"
Enter fullscreen mode Exit fullscreen mode

箭頭函式 ( Arrow Function )

在 ES6 中,引入了箭頭函式的概念。箭頭函式是一種更簡潔的函式語法,它使用 => 符號來定義函式。箭頭函式有一些特別的行為:

  • 箭頭函式沒有自己的 this 關鍵字,它繼承了外部執行上下文的 this 值。
  • 箭頭函式總是匿名的,因此不能使用 function 關鍵字來命名箭頭函式。
  • 箭頭函式的 return 關鍵字是隱式的,因此不需要顯式地返回值。

以下是一個使用箭頭函式的簡單範例:

const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map(number => number * 2);

console.log(doubledNumbers); // [2, 4, 6, 8, 10]
Enter fullscreen mode Exit fullscreen mode

在此範例中,箭頭函式被用於將 numbers 數組中的每個數字乘以 2。這個函式使用了箭頭函式簡潔的語法,並返回一個新的數組。

Top comments (0)