Jeff的隨手筆記

學習當一個前端工程師

0%

『JavaScript 基礎』 Function

Imgur

這是一門在Udemy 課程,是同學介紹的。主要是因為想要運用到過年前這段時間好好的增進自己的JavaScript的基礎能力,讓自己能往前端工程師更近一步。主要還是會以筆記的形式做呈現!


In JavaScript, functions are objects.

First class functions

指的是任何你可以對函式做出任何對其他型別(Objects, String, Boolean, Numbers)也做得到事,包括將 Function 指定成一個變數,帶入另一個函式中等等 。
JavaScript 中的 function 就符合 First Class Functions 這樣的特性:
函式只是物件的一種
可以將 function 儲存成變數
可以將 function 當成參數代入另一個 function 中
可以在一個 function 中回傳另一個 function
function 跟物件一樣有屬性(property)

回歸主題:In JavaScript, functions are objects.
這句話怎麼說呢?
function就像其他object一樣,他會儲存在記憶體中,並且有兩個特殊的部分:name 和 code。

  • Name:
    function 的名稱是可有可無的,它可以是一個匿名函式(anonymous function)
  • code:
    可以透過 () 來加以執行(invoke)。

看下面的範例:

1
2
3
4
5
6
7
8
function greet() {
console.log('Hello');
}

greet.language = 'english';
greet();
console.log(greet.language);

輸出:

1
2
Hello
english

因為 function 可以當作物件來使用,所以可以直接用.來建立該物件的屬性和值,屬性的名稱為 language,值為 english。

當我今天要呼叫這個function,只要打該函式的名稱,後面接上括號 () 就可以去執行該函式
這樣的例子說明了,function只是一種特殊的物件,它可以被當作物件來使用。


Expressions(表達式) 跟 Statements(陳述句) 的名詞解釋

Expressions

表達式是產生值的代碼(An expression is a unit of code that results in a value.)
在JavaScript中,任何的expressions 都會創造一個值,但這個個值不一定會要在變數裡面。
例子:

[Imgur](https://i.imgur.com/PnWEVEL.png)
在瀏覽器的 console 中輸入 a = 3 時,它會直接回傳 3 這個值;輸入 2 + 3 的時候,它會直接回傳 5;輸入 a = { } 的時候,它會回傳一個為物件的值。這種輸入一段程式後,會直接取得回傳一個值的程式內容,我們就稱為 Expressions。
簡單來說:只要你輸入的那串程式執行後能直接回傳一個值,那麼它就是個 expression。

Statements

命令,並且進行一系列操作,特徵為不會回傳一個結果 。只用說的可能不好理解,我們直接用code來說

1
2
3
if (a === 3) {
console.log('Hello');
}

這是一段陳述句(Statements),因為它不會直接回傳一個值,所以我們不能將它指定為一個變數:

1
2
3
4
// ❌ 錯誤寫法
var b = if (a === 3) {
console.log('Hello');
}

Function Expressions 和 Function Statements

在 JavaScript 中,Function 就是物件的一種,它可以透過 Expression 或 Statements 的方式加以操作。

Function Statements

1
2
3
function greet() {
console.log('Hi');
}

在之前我們有說到,在JavaScript中function 就是物件,所以用物件的概念來理解函式的話,這個函式屬性 name 的值是 greeting,這個函式 code 屬性的值為 console.log(‘hi’)。

Imgur

當我們要執行這個函式的時候,只要輸入 greet() 就可以了。
而Function Statements 的特色在於,它在程式執行的最開始,該函式就會透過 hoisting 先被儲存在記憶體中,因此我們可以在一開始就呼叫function 而不會出現錯誤:

1
2
3
4
greet();   // 'Hi'
function greet() {
console.log('Hi');
}

Function Expressions

1
2
3
var anonymousGreet = function() {
console.log('hi');
};

function(){ … } 這段就是 Function Expression,現在我們則把這個函式表達式的值存在 anonymousGreet 這個變數內。

剛剛我們有提到JavaScript中的function 就是物件,因此在這個範例,我們從物件的角度來看function:

Imgur
我們先建立了一個function,但這個function的 name 屬性並沒有給它值,之所以可以這麼做是因為,我們在 function expression 前面已經把它指定到一個變數(anonymousGreet),所以可以直接用這個變數名稱來指稱這個函式。對於這種 name 屬性沒有值的function,就叫做匿名函式(anonymous function 或 function literal)

同樣的要執行它也只需再變數名稱後加上()就可以了。

但這邊要特別注意,跟Function Statements 不同的是,我們不可以在還沒宣告變數時就呼叫他:

1
2
3
4
5
6
// ❌ 錯誤寫法
anonymousGreet();

const anonymousGreet = function() {
console.log('Hello');
};

因為在一開始執行程式初期,只會先建立並儲存變數名稱到記憶體中,但程式內容不會一併儲存進去(這時候 anonymousGreet 的值會是 undefined),是不是很眼熟,沒錯就是hoisting。


接下來我們要談談callback function:

我們建立了一個function,如下:

1
2
3
function log(a) {
console.log(a);
}

因為我們有設定參數,所以這時候我們呼叫這個function時,就必須要給參數,給參數的方式有兩個:

1
2
3
4
5
// 方法1
const b = 3;
log(b);
// 方法2
log(3)

兩個的方法輸出都會是3。只是一個是用變數裝,一個是直接把值放到參數中。

那如果我要放的是一個function並執行呢?也是可以的

1
2
3
4
5
6
7
8
9
function log(a) {
a();
}

var anonymousGreet = function() {
console.log('Hi');
};

log(anonymousGreet);

或是我們可以寫的更簡化些:

1
2
3
4
5
6
7
function log(a) {
a();
}

log(function() {
console.log('Hi');
});

這樣,就可以在不用建立函式的情況下,直接去執行一個匿名函式。

由於 JavaScript 非同步的特性,若想要確保程式執行的順序,常常會使用到回呼函式(callback function)這種方式,它內部的做法其實也就是把函式傳入另一個函式中去呼叫。