JS Functions (Code Blocks)
1. Function Basic Examples
// Example 1
function myFunction() {
console.log('Hello!');
}
// Example 2 (with paramters)
function myMath(p1, p2) {
return p1 * p2; // The function returns the product of p1 and p2
}
console.log( myMath(4, 3) );
// Example 3 (another ways to declare function)
function func1(){ console.log("111"); }
var func2 = function(){ console.log("222"); }
var func4 = function func3(){ console.log("333"); } // invalid syntax
var func5 = func2;
func1(); //111
func2(); //222
func3(); //ReferenceError: func3 is not defined
func4(); //333
func5(); //222
2. Function 定義本身也是一種變數,可被印出
- 有
()
運算子才是執行 Function
// declaration function
function toCelsius(f) {
return (5/9) * (f-32);
}
console.log( toCelsius ); // "ƒ toCelsius(f) { return (5/9) * (f-32); }" (return the function definition)
console.log( toCelsius(77) ); //25
console.log( typeof toCelsius ); //"function"
console.log( typeof toCelsius(77) ); //"number"
3. Function Definition
3.1. 宣告函數在語法上有 4 種方式
ES6 多了第 5 種 —— Arrow Function
1. 宣告式 (function declarations)
//syntax 1: Function Declarations (Hoisting)
console.log(myFunc1); // ƒ myFunc1(a, b) {return a * b;}
function myFunc1(a, b) {
return a * b;
}
2. 匿名表達式 (function expressions w/o function name)
- 此方式定義的 function 實際上是 anonymous function (a function without a name)
- 只是將 function body 存在某個變數裡,該變數名稱不等於 function 名稱
//syntax 2: Function Expressions w/o function name
var myFunc2 = function (a, b) {return a * b};
console.log(myFunc2); // ƒ (a, b) {return a * b}
3. 具名表達式 (function expressions w/ function name) (沒事別用)
- 定義的 function 印出來會有 function name (不等於變數名稱)
- 但無法直接透過該 function name 呼叫 ,所以該 function name 基本上沒用
- (目前理解:因為該 function 仍不算正式宣告於此 scope,對此 scope 來說不存在該 name,所以無法直接透過 function name 呼叫)
//syntax 3: Function Expressions w/ function name
var myFunc2 = function aaa(a, b) {return a * b};
console.log(myFunc2); // ƒ aaa(a, b) {return a * b}
console.log(aaa); // Uncaught ReferenceError: aaa is not defined
4. 建構子式 (function constructor) (沒事別用)
- with a built-in JavaScript function constructor called
Function()
- it's unnecessary to use this way
//syntax 4: Function Constructor
var myFunc3 = new Function("a", "b", "return a * b");
console.log(myFunc3); // ƒ anonymous(a,b /*``*/) { return a * b }
3.2. 各方式差異
只有宣告式有 Hoisting 效果,expression 和 constructor 都無
ES6 的 Arrow Function 也無
印出 Function 定義有些微差異
- expression w/o name 不會有 function名稱
- constructor 會多一些符號
4. Functions 基本規則
A Function is much the same as a Procedure or a Subroutine, in other programming languages.
- Function names :
- 和變數命名規則相同
- 函數參數:
- Function parameters : 函數 定義時 ,列在函數傳入參數定義裡的名稱 (are the names listed in the function definition.)
- Function arguments : 當函數 實際被呼叫時 ,傳入的實際值 (are the real values received by the function when it is invoked.)
- arguements 和 paramters 對函數來說都是 local 變數 (Inside the function, the arguments (the parameters) behave as local variables.)
- Function Return : When JavaScript reaches a return statement, the function will stop executing.
- Function Signature:
- 只有變數名稱(無視參數)
- 等於不存在 overloadding
- 容許重複定義同名稱的 function,等於重複宣告,依定義順序以最後一個為準
Example 1:
myFunc();
function myFunc(){
console.log('111');
}
function myFunc(p1){
console.log('222');
}
//***** result *****
//222
Example 2:
myFunc();
function myFunc(){
console.log('111');
}
var myFunc = function(p1){
console.log('222');
}
myFunc();
//***** result *****
//111 (because of Hosting)
//222
5. Function Parameters & Arguments
5.1. Parameters v.s. Arguments
mynote:
- arguments 是實際傳入的參數的陣列
- parameters 是定義時自己命名的參數名稱,但實際呼叫時不一定會被傳入;如果沒被傳入,此時 type 是
undefined
Example:
function myFunc(a1, a2, a3){
console.log("typeof a1=", typeof a1);
console.log("a1=", a1);
console.log("typeof arguments=", typeof arguments);
console.log("arguments=", arguments);
console.log("typeof arguments[0]=", typeof arguments[0]);
console.log("arguments[0]=", arguments[0]);
}
console.log("====trial 1");
myFunc();
console.log("====trial 2");
myFunc("apple", "banana", "cookie", "egg");
Result:
====trial 1
typeof a1= undefined
a1= undefined
typeof arguments= object
arguments= [callee: ƒ, Symbol(Symbol.iterator): ƒ]
typeof arguments[0]= undefined
arguments[0]= undefined
====trial 2
typeof a1= string
a1= apple
typeof arguments= object
arguments= (4) ["apple", "banana", "cookie", "egg", callee: ƒ, Symbol(Symbol.iterator): ƒ]
typeof arguments[0]= string
arguments[0]= apple
5.2. Function Parameter Defaults
避免函數呼叫時沒傳到所有參數 (called with a missing argument),要額外為參數設定預設值:
myFunction(5);
function myFunction(x, y) {
if (y === undefined) {
y = 99;
}
console.log(y);
}
//**********result*********
//99
ES6 有更簡潔的語法:
myFunction(5);
function myFunction(x, y=99) {
console.log(y);
}
//**********result*********
//99
5.3. Function Arguments Object
- JavaScript functions have a built-in object called the arguments object.
- 因為 arguments 可以得到所有參數 (不管有沒有定義參數),因此可以做到以下應用技巧:
x = findMax(1, 123, 500, 115, 44, 88);
x = sumAll(1, 123, 500, 115, 44, 88);
function findMax() {
var i;
var max = -Infinity;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
function sumAll() {
var i;
var sum = 0;
for (i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
Note: ES6 的 Arrow Function 不能使用 arguments,讓 function 使用上更嚴謹。
6. Function Invocation (函數呼叫)
6.1. 有三種被呼叫的時機
- When an event occurs (e.g. when an user clicks a button)
- When it is invoked (called) from JavaScript code (e.g. 直接呼叫)
- Automatically (self invoked)
6.2. Self-Invoking Functions (立即函數)
Intro
Function expressions
can be made " self-invoking ".- A self-invoking expression 會自動執行,不用呼叫
- 要在 function 前後用括號包起來,來指定這是一個 function expression
- function expression 語法可以分 匿名 和 具名 ,但此處 具名 仍沒什麼意義,無法另外呼叫
- 在 expression 尾端加上
()
就會自動執行
You cannot self-invoke a function declaration.
mynote: 一開始不懂這樣寫的用意在哪,覺得很多餘,和不用 function block 包起來效果一樣
Examples
// syntax 1: an anonymous self-invoking function
(function () {
var x = "Hello!!"; // I will invoke myself
console.log('222');
})();
// syntax 2: a self-invoking function with naming
(function abc () {
var x = "Hello!!"; // I will invoke myself
console.log('222');
})();
abc(); // ReferenceError: abc is not defined
用途 1 : 封裝一次性 local scope
- 封裝一段想立刻執行的 code,建立一次性的 local scope
- 讓一次性變數的生命週期留在函數內,避免影響到後續全域變數
Before:
var x = "Hello";
console.log(x);
console.log('Do something.....');
console.log(x); // x is still alive
//******** reuslt **********
// "Hello"
// "Do something....."
// "Hello"
After:
(function () {
var x = "Hello"; // I will invoke myself
console.log(x);
})();
console.log('Do something.....');
console.log(x);
//******** reuslt **********
// "Hello"
// "Do something....."
// ReferenceError: x is not defined
用途 2 : 閉包應用
將一次性 local scope 裡的物件或變數回傳出來
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
console.log(add);
console.log(add());
console.log(add());
// *****result*****
// ƒ () {return counter += 1;}
// 1
// 2
效果和以下不一樣:(以下只是將一個函數物件放入 add
,並沒有立即執行)
var add = function() {
var counter = 0;
return function () {return counter += 1;}
};
console.log(add);
console.log(add());
console.log(add());
// *****result*****
// ƒ () {
// var counter = 0;
// return function () {return counter += 1;}
// }
// ƒ () {return counter += 1;}
// ƒ () {return counter += 1;}
用途 3 : 為物件的屬性產生動態值
var person = {
age: (function (){ return 18; })()
};
console.log(person.age); //18
用途 4 : 字串轉 function
可以把純字串轉成 function (因應 JSON 不支援儲存 function 型態的資料)
var text = '{ "name":"John", "age":"function () {return 30;}", "city":"New York"}';
var obj = JSON.parse(text);
console.log(typeof obj.age); //"string"
console.log(obj.age); //"function () {return 30;}"
var ageFunc = eval("(" + obj.age + ")");
console.log(ageFunc); //ƒ () {return 30;}
console.log(ageFunc()); //30
用途 5 : 瀏覽器書籤小工具
- 可以把語法存成瀏覽器的書籤,點下去就會立即執行
- E.g. 常見的
解除右鍵
工具
javascript:(function() { function R(a){ona = "on"+a; if(window.addEventListener) window.addEventListener(a, function (e) { for(var n=e.originalTarget; n; n=n.parentNode) n[ona]=null; }, true); window[ona]=null; document[ona]=null; if(document.body) document.body[ona]=null; } R("contextmenu"); R("click"); R("mousedown"); R("mouseup"); R("selectstart");})()
7. Functions are Objects
- JavaScript functions 也是 objects
- 雖然
typeof
回傳 "function" - 因為有 properties 和 methods,所以 objects 共通有的 methods,function 也有 (e.g.
toString()
)
- 雖然
function myFunc(a, b) { return a * b; }
console.log(myFunc.toString()); // "function myFunc(a, b) { return a * b; }"
- 定義一個 function 為某 object 的 property,稱為一個 method to the object.
- 定義一個 function 用來 new 新 objects,稱為 object constructor.
8. Function Constructors
(產生類似物件效果的用法)
如果用
new
去呼叫一個 function,稱為一個 constructor invocation- 語法看起來像是 new 一個 function,但因為在 JS 裡 function 是物件,所以實際上等於產生一個物件
- 這個 function 的定義就如同 constructor
- 新物件會繼承該 function 內的 properties 和 methods
The
this
keyword in the constructor does not have a value.
The value ofthis
will be the new object created when the function is invoked.
// This is a function constructor:
function Person(arg1, arg2) {
this.firstName = arg1;
this.lastName = arg2;
this.sayHi = function(){
return "Hi, I'm " + this.firstName + " " + this.lastName;
}
}
// This creates a new object
var x = new Person("John", "Doe");
console.log(x);
console.log(x.firstName);
console.log(x.sayHi());
//====== result:
//Person {firstName: "John", lastName: "Doe", sayHi: ƒ}
//John
//Hi, I'm John Doe
9. Functions are Object Methods
- 所有的 JavaScript functions 都是 object 的 method
var myObject = {
firstName:"John",
lastName: "Doe",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
myObject.fullName(); // Will return "John Doe"
- 如果某 function 不是特定 object 的 method,就是 global object 的 method
function myFunction(a, b) {
return a * b;
}
//myFunction() and window.myFunction() is the same function
myFunction(10, 2);
window.myFunction(10, 2);
Using the window object as a variable can easily crash your program.
10. Nested Functions (巢狀 Function)
inner function
function add() {
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
console.log(add);
console.log(add());
console.log(add());
console.log(add());
// *****result*****
// ƒ add() {
// var counter = 0;
// function plus() {counter += 1;}
// plus();
// return counter;
// }
// 1
// 1
// 1
11. Callback
A callback function is a function passed as a parameter to another function.