本篇章主要是我自己整理出來的 (大多數是爬了各網站、教學文章)
我把它當作學習筆記, 如果有也侵害著作權
請留言或是 E-mail: lioajimzen@gmail.com
- 宣告式 (Function Declarations)>>
- 匿名表達式 (Function Expressions without Function Name)>>
- 具名表達式 (Function Expressions / Function Name)>>
- 建構子式 (Function Constructor)>>
- 箭頭函式 (Arrow Function)>>
- Arrow Functions ES5與ES6的不同之處
- Arrow Function基本語法結構
- 參數1, 參數2, … , 參數N (含Return )
- 陳述式與表達式
- 當只有一個參數時, 可去除括號
- Arrow Function進階語法
- SetTimeout 箭頭函式結構
- SetInterval 箭頭函示結構
- This 與我們分不開>>
- This :一般函式內 結構與功能
- This :Arrow Function內 結構功能
- This 提取Arrow Function內部值
- 用setInterval 將一般函式this 物件p帶出
- 在 ECMAScript 3/5 裡面,this 可透過指派 this 值。
- Strict Mode 嚴格模式的關係
- Arrow function 沒有自己的this
- This: Strict Mode
資料參考來源: 1.你不可不知的 JavaScript 二三事#Day19:函數定義 (Function Definition) 的 100 種寫法 2.MDN_Web 3.Fooish_Javascript 4.JS-ES6箭頭函數 5.Arrow function expressions 6.六角學院課程
<函式的概要/Function Outline>
函式說的白話…
把一連串邏輯判斷+運算式, 將他們寫成一個 “功能容器”, 每次你要用他們的時候, 呼叫他們即可!
又或者可以將你定義的眾多“屬性“清單包裝在Function 裡面
<一般函式定義/Function Define>
一個函式的定義由一系列的函式”關鍵字”組成, 依次為:
- 用
function
關鍵字來宣告一個函數 - 我們指定這個函數的名稱
functionName
- 包圍在括號()中,並由逗號區隔每一個函式參數。
- 包圍在大括號{}中,用來定義函式內功能的”物件”,而且這些物件已經給予記憶體空間。( 通常拿來建立物屬性件使用 )
函式_結構 Construct Function>>
function functionName(parameter1, parameter2, ...) {
statements
return value;
}
可以不包含參數&不回傳/None Return>>
若你把 return 陳述式刪除, 當這個function 被呼叫之後… 經處理的結果若沒有 “受眾” , 結果就會顯示 undefined.
我的文章有寫關於 undefined 就是這篇。
無Return 結構:
function functionName() {
//只有陳述式
statements
}
// 輸出結果 :
undefined
函式範例>>
函式名稱: squre
在squre函式裡面的算式= number*2 , 運算完成後會把該值 resultVal 作回傳。
let resultVal;
let number;
function square(number) {
resultVal=number * number;
return resultVal
}
console.log(square(10));
-----------------------------------
// 輸出結果
100
<函式回傳/Return Satement >
參考資料:
英文原文: The return statement ends function execution and specifies a value to be returned to the function caller.
函式回傳:
當你呼叫這個函式, 此函式的處理功能…. 接手過來處裡你的資料, 處理完之後把這個處理好的值丟到一個內定記憶體區間或式暫存區, 然後再把這個暫存值丟給”呼叫者”, 此時執行到return 陳述式時也代表此函式已經執行完畢!
function getRectArea(width, height) {
if (width > 0 && height > 0) {
return width * height;
}
return 0;
}
-----------------------------------
console.log(getRectArea(3, 4));
// expected output: 12
console.log(getRectArea(-3, 4));
// expected output: 0
Return的各種表示法>>
return;
return true;
return false;
return x;
return x + y / 3;
<各種函式的寫法/Various Functions Writing>
- 宣告式 (Function Declarations)
- 匿名表達式 (Function Expressions w/o Function Name)
- 具名表達式 (Function Expressions w/ Function Name)
- 建構子式 (Function Constructor)
- 箭頭函數 (Arrow Function) – ES6 參考資料
宣告式 (Function Declarations)>>
- 最標準的寫法。
- 使用
function
關鍵字作函數的宣告和定義。 - 具有 Hoisting 提升效果。
console.log(myFunc);
console.log(myFunc(3, 6));
function myFunc(a, b) {
return a + b;
}
-----------------------------------
// 執行結果
//function myFunc(a, b) {
return a + b;
}
//9
匿名表達式 (Function Expressions without Function Name)>>
- 先宣告一個變數,再定義一個函數內容放到該變數裡。
- 此方式定義的函數實際上是匿名函數 (a function without a name),將函數定義的主體,存在你定義的變數裡。
- 變數名稱不等於函數名稱。
- 不具 Hoisting 提升效果。
console.log(myFunc);
// console.log(myFunc(3, 6)); // TypeError: myFunc is not a function
let myFunc = function (a, b) {
return a + b;
};
console.log(myFunc);
console.log(myFunc(3, 6));
-----------------------------------
//執行結果
//undefined
//ƒ (a, b) {
return a + b;
}
//9
具名表達式 (Function Expressions / Function Name)>>
- 和「匿名表達式」相似,差別在定義函數內容時,有給予一個函數名稱 (Function name)。
- 定義的函數印出來會有函數名稱(不等於變數名稱)。
- 但無法直接透過該函數名稱呼叫。
- 不具 Hoisting 提升效果。
console.log(myFunc);
// console.log(myFunc(3, 6)); // TypeError: myFunc is not a function
var myFunc = function aaa(a, b) {
return a + b;
};
console.log(myFunc);
console.log(myFunc(3, 6));
// console.log(aaa); // ReferenceError: aaa is not defined
-----------------------------------
//執行結果
//undefined
//ƒ aaa(a, b) {
return a + b;
}
//9
建構子式 (Function Constructor)>>
說到建構子我們不得不提 new 這個Keyword,因為提到new 我們就要有個概念: 我們正在建立物件!
- 先宣告一個變數,再用 JavaScript 內建的函數建構子
Function()
去定義函數內容,放到該變數裡。 - 用
Function()
定義的函數自動被給予函數名稱anonymous
,但和「具名表達式」一樣,都無法直接透過該函數名稱呼叫。 - 不具有 Hoisting 提升效果。
console.log(myFunc);
// console.log(myFunc(3, 6)); // TypeError: myFunc is not a function
var myFunc = new Function("a", "b", "return a + b");
console.log(myFunc);
console.log(myFunc(3, 6));
-----------------------------------
//執行結果 // undefined
// ƒ anonymous(a,b
) {
return a + b
}
//9
箭頭函式 (Arrow Function)>>
參考資料: MDN_Web_箭頭函式 , 鐵人賽 (Arrow function) 卡斯柏
An arrow function expression is a compact alternative to a traditional function expression, but is limited and can’t be used in all situations.
箭頭函式 有著比一般函式表示法更精簡的表示法, 但箭頭函式並非一體適用….
箭頭函式也有它的極限啊!
- Arrow functions don’t have their own bindings to
this
,arguments
orsuper
, and should not be used as methods. - Arrow functions don’t have access to the
new.target
keyword. - Arrow functions aren’t suitable for
call
,apply
andbind
methods, which generally rely on establishing a scope. - Arrow functions cannot be used as constructors.
- Arrow functions cannot use
yield
, within its body.
- Arrow functions沒有自己的 this、arguments 或 super 可綁定,不應該作為 方法 Method。
- Arrow functions無權造訪 new.target 關鍵字。
- Arrow functions不適用於調用、應用和綁定方法,這些方法通常依賴於建立作用域。
- Arrow functions不能用在建立建構子。
- Arrow functions不能在函式內使用 yield。
Arrow Functions ES5與ES6的不同之處
底下範例碼參考: Arrow function js_github
//ES5 版本
var circle = function(r) {
var PI = 3.14 ;
return r*r*PI
}
console.log(circle(2))
//執行結果 12.56
//ES6 版本
const circle = (r) => {
const PI = 3.14 ;
return r*r*PI
}
console.log(circle(2))
//執行結果 12.56
Arrow Function基本語法結構
參數1, 參數2, … , 參數N (含Return )
(參數1, 參數2, …, 參數N) => { 陳述式; }
(參數1, 參數2, …, 參數N) => 表達式;
陳述式與表達式
當只有一個參數時, 可去除括號
(參數1)=> { statements }
//若無參數,就一定要加括號:
() => { statements }
Arrow Function進階語法
// 用大括號將內容括起來,返回一個物件字面值表示法:
params => ({foo: bar})
// 支援其餘參數與預設參數
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
statements }
// 也支援 parameter list 的解構
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f();
//執行結果 6
//物件內的屬性們
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
// -----這段函式會輸出[8, 6, 7, 9]這個陣列
elements.map(function(element) {
return element.length;
});
// -----上方一般的函式,可以被改寫成下方的箭頭函式
elements.map((element) => {
return element.length;
});
//執行結果 [8, 6, 7, 9]
// -----如果輸入的參數只有一個,我們可以移除掉外面的括號
elements.map(element => {
return element.length;
});
//執行結果 [8, 6, 7, 9]
// -----當箭頭函式裡的內容只有'return'的時候,我們刪除return和外面的大括號
elements.map(element => element.length);
//執行結果 [8, 6, 7, 9]
// -----在這個範例中,因為我們只需要length這個屬性,所以也可以使用解構賦值:
// -----下方的'length'對應到我們想取得的屬性,而'lengthFooBArX'只是很普通的變數名稱,
// -----可以被任意修改成你想要的名字
elements.map(({ length: lengthFooBArX }) => lengthFooBArX);
// [8, 6, 7, 9]
// -----上面解構賦值之後的參數也可以被改寫為下面這樣。但要注意的是,在這個範例中,
// -----我們不是要指定'length'這個值給一個虛構的屬性,而是這個變數的名稱'length'本身就是
// -----用來當成我們想從物件上取得的屬性
elements.map(({ length }) => length);
//執行結果 [8, 6, 7, 9]
SetTimeout 箭頭函式結構
setTimeout(() => {
// -----100 milliseconds 之後執行
}, 100);
SetInterval 箭頭函示結構
setInterval(()=> {
// -----100 milliseconds 這期間一直處裡。
},100);
This 與我們分不開>>
參考資料:
PjChener_Arrow Function_This, PJCHENder
那些沒告訴你的小細節this
解釋 JavaScript 中 this 的值?|ExplainThis
一般函式內,每個新函式是依據如何被呼叫來定義自己的 this 變數。
This :一般函式內 結構與功能
- 在建構子時是一個新物件 (這很重要)
- 在呼叫嚴格模式函數時是 undefined
- 以物件方法呼叫時則為”基礎物件”
利用建立物件, 函式帶出數值
function User() {
this.name = 'Bob';
}
function AnotherUser() {
this.name = 'Hugo';
}
var user1 = new User();
var user2 = new AnotherUser();
console.log(user1.name);
console.log(user2.name);
//顯示結果
Bob
Hugo
This :Arrow Function內 結構功能
//-----一般函式
function User() {
this.name = "Bob";
return this;
}
console.log(this.name);
//-----箭頭函式
()=>{
this.name ="It is Arrow Functions";
}
console.log(this.name);
console.log(typeof this.name);
//顯示結果
(空物件)
It is Arrow Functions
string
This 提取Arrow Function內部值
// Arrow function 1
()=>{
this.name ="It is Arrow Functions";
}
console.log(this.name);
console.log(typeof this.name);
//顯示結果
//It is Arrow Functions
//It is Arrow Functions
//string
- 箭頭函數(Arrow Functions) — this是定義時的對象, 不是在使用的物件。
- 傳統Function語法 — this是使用、呼叫(call)時的對象。
用setInterval 將一般函式this 物件p帶出
function Person() {
// Person() 建構式將 this 定義為它自己的一個實體
this.agegrowing = 0;
setInterval(function growingUp() {
// 在非嚴格模式stric mode下, growUp() 函式把 this 定義為全域物件
// (因為那是 growingUp()執行的所在),
// 與 Person() 建構式所定義的 this 有所不同
this.agegrowing++;
}, 3000);
}
// 在全域做另一個物件 p
var p = new Person();
console.log(p);
在 ECMAScript 3/5 裡面,this 可透過指派 this 值。
function Person() {
var me = this;
me.age = 0;
setInterval(function growUp() {
// 這個 callback 參考 `self` 變數,為預期中的物件。
mee.age++;
}, 1000);
}
透過 bind 函式來綁定 this
變數到指定函式(上面為例,就是 growingUp()
函式)。
箭頭函式不會擁有自己的 this
; 箭頭函式遵循 “常規變量查找規則“。
在當前範圍中搜索不到 this 變量時,他們最終會尋找其作用域。
Strict Mode 嚴格模式的關係
由於
this 變數具有詞彙上綁定意義,故嚴格模式的宣告對 this 的作用將被忽略。
Arrow function 沒有自己的this
// Arrow function 1
()=>{
this.name ="It is Arrow Functions";
return this;
}
console.log(this.name);
// Arrow function 2
var ArrowObject =()=>{
this.name ="It is ArrowObject Functions";
}
ArrowObject();
console.log(this.name);
console.log(typeof this.name);
This: None Strict Mode
const obj = { // does not create a new scope
i: 10,
b: () => console.log(this.i, this),
c() {
console.log(this.i, this);
},
}
obj.b(); // prints undefined, Window { /* … */ } (or the global object)
obj.c(); // prints 10, Object { /* … */ }
This: Strict Mode
'use strict';
const obj = { // does not create a new scope
i: 10,
b: () => console.log(this.i, this),
c() {
console.log(this.i, this);
},
}
obj.b(); // prints undefined, Window { /* … */ } (or the global object)
obj.c(); // prints 10, Object { /* … */ }
結語
有點想不太出來結語要寫甚麼, 光是要弄懂一般函式 vs 箭頭函式 + 蒐集資料就挺累人的