使用函式可以讓我們執行效率提升,不用重複撰寫,只需幾行語法便可以達到快速的運算、或是功能的執行。以下範例為數羊計數,透過函式以及迴圈,以幫助設定計數的起始以及終點,並快速的執行範圍內的計數。
1 | //為什麼我們需要function |
- 也可以return後面接物件
- 回傳結果為20
- 回傳結果為20
簡單練習題
- 創建空陣列,並於陣列中放數1,2,3,…10
要放入return,否則會出現undefined
- 也可以將參數改成兩個數
1 | function generateArray(a, b) { //a,b 可以改為 from,to |
return
函式中一放進return,在函式,return後面的部分就不會運行了
不需要知道結果
需要回傳值
- 參數:函式後面要傳入的值
- 引數:真正傳進去的東西
- Arguments:為類陣列,屬於物件
表達式(Expression)與陳述句(Statement)的差異
- 表達式:會回傳值
- 陳述句:不會回傳值 (if…else,switch,等控制流程)
使用函式陳述式(Function Statement)與函式表達式(Function Expression)
- 函式陳述式(Function Statement):在使用函式之前,放入helloFunctionStatement();是可以執行
1 | //helloFunctionStatement(); 放在前面沒關係 |
- 函式表達式(Function Expression):反之,要放在宣告之後:::warning
1
2
3
4
5
6//helloFunctionExpression(); 放前面,會出現錯誤
var helloFunctionExpression = function () {
console.log('this is Function Expression ');
}
helloFunctionExpression();
因為hoisting(變數提升)的關係
:::
變數能夠影響的範圍作用域( Scope 作用域:變數可以影響的範圍 )
- 在function中,所宣告的 var a = 50;,範圍就只有涵蓋在函式中,不會影響到外面
1 | var a = 100; |
- 如果函式中,宣吿某變數,沒有加var/let,該變數就會影響外部
1
2
3
4
5
6
7var a = 100;
function helloWorld() {
a = 50;
console.log('function:', a);
}
helloWorld();
console.log('外部:', a);
全域變數與區域變數
1 | var y = 1; //在外面宣告為 全域變數 |
區域變數:在function中進行宣告
1
2
3
4function abc() {
//var,let,const
var x = 1
}不是變數 => 全域的屬性
- z=1;
- 也可以用window來存取
回呼函數 Callback Function
- 把函數做為參數傳遞
- 當檔案讀取完畢時,請來執行這個 function,並且把結果傳進來
- heyFunc(console.log)->console.log 可以替換別的
1 | function heyFunc(myFunction) { |
- 非同步(Asynchronous):回呼常用來延續非同步行動完成後的程式執行
其他介紹 超入門 JavaScript 教學 13 - 回呼函式 callback
- 以下範例:讓cb接到shout這個函式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19function shout() {
console.log('hello,i am done')
}
function countToSeven(cb) {
for (var i = 1; i <= 7; i++) {
console.log(i);
}
if (typeof cb === 'fuction')
cb(); //啟動shout函式
}
countToSeven(); //會數1-7
//要數完七之後,說'hello,i am done
countToSeven(shout);
countToSeven(1);//1不是函式,所以在if判斷句終止
//每隔一段時間,幫我做一次
setInterval(shout, 2 * 1000);//每隔兩秒執行sout
//在多少時間之後,幫我執行
setTimeout(shout, 1 * 1000)js內建函式
- 每隔一段時間,幫我做一次
setInterval(shout, 2 * 1000);
//每隔兩秒執行sout - 在多少時間之後,幫我執行
setTimeout(shout, 1 * 1000)
- 每隔一段時間,幫我做一次
參考資料:
重新認識 JavaScript: Day 18 Callback Function 與 IIFE
JavaScript 中的同步與非同步(上):先成為 callback 大師吧!
JS20min Day — 18 關於回呼生活化 (Callback)
匿名函式
- heyFunc裡面的function沒有名稱
1
2
3
4
5
6
7
8
9function heyFunc(myFunction) {
myFunction('hi');
}
heyFunc(function (message) {
console.log('message is:', message);
});
//message is:hi
</script>
立即函式(IIFE)
Luka
- 它是沒有名字的函式,要立即調用
- 不讓函式內的變數污染到外面的東係
- 讓jquery的$$變成是jquery使用
1
2
3
4
5(function (name) {
var str = 'Hi ' + name + '!';
console.log(str);
})('Sam');
- 一般常見寫法
1
2
3
4
5var sayHi = function (name) {
var str = 'Hi ' + name + '!';
console.log(str);
}('Peter')//在後面立即執行
// sayHi("Peter");
[筆記] 談談JavaScript中的IIFEs(Immediately Invoked Functions Expressions)
[筆記] 為什麼我們要用IIFEs(Immediately Invoked Functions Expressions)
hoisting 變數提升淺談
js的變數與函式的宣告提升
不管在哪一行使用了變數,都視為第一行宣告
比較好的流程 By 彭彭
但在js有hoisting 變數提升
- 就算把變數宣告放在後面,依然可以運作(會將
var x
提升到最前面)
進一步細節…
電腦解讀如下
var x
會提升
結果會印出undefined
在函示fuction的變數提升
- 先宣告函式,在能呼叫函式執行
- 在js先呼叫,依然可以運作
其他狀況…(把函式裝到變數中當作資料)
- 在此情形,它會出現錯誤,回報test不是一個函式
- 程式的解讀 :point_down:
- 只有var test被提升
程式柴
- 沒有宣告
常用的內建函式
Number類型
- parseInt 是取整數,若遇到如20.35,就只會取到20
- 遇到小數點且要保留的時候,使用parseFloat
- 結果為30.35
Math.ceil()
=> 無條件進位Math.floor()
=> 無條件捨去Math.round()
=> 四捨五入Math.sqrt()
=> 開根號Math.pow()
=> 次方Math.radom()
=> 產生隨機數(0-1,不包含1)toString()
=> 數字轉字串- 或是加空字串
String類型
toUpperCase
=> 轉大寫toLowerCase
=> 轉小寫indexOf
=> 找出字串中,單字的索引(用於檢查某字是否存在字串中)replace()
=> 取代- 用正規表達式來選擇 某些字
- 用正規表達式來選擇 某些字
split()
=> 切字串1
2
3
4//split較常使用的情形
//當資料為一連串字串,利用逗號切割 變成陣列,比較好運用
var str = 'data1,data2,data3,data4';
console.log(str.split(','));trim()
=>從一個字符串的两端刪除空白字符1
2
3
4
5
6
7const greeting = ' Hello world! ';
console.log(greeting);
// expected output: " Hello world! ";
console.log(greeting.trim());
// expected output: "Hello world!";
Array 類型
- Array.prototype.join()
- 方法會將陣列(或一個類陣列(array-like)物件)中所有的元素連接、合併成一個 ‘字串’,並回傳此字串(在陣列中每個元素間插入設定的東西)
1
2
3
4
5
6
7
8
9
10const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join());
// expected output: "Fire,Air,Water" //會變成字串
console.log(elements.join(''));
// expected output: "FireAirWater"
console.log(elements.join('-'));
// expected output: "Fire-Air-Water" - Array.prototype.map()
- 建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。
1
2
3
4
5
6var arr = [1, 2, 3];
console.log(
arr.map(function (x) {
return x * -1
})
)
1 | //也可以接著寫下去 |
過濾
1
2
3
4
5
6
7
8
9
10
11var arr = [1, 2, 3, -5, 3, -2];
console.log(
arr
.map(function (x) {
return x * 2
})
.filter(function (x) {
return x > 0
})
//把負數過濾掉,留下正數
)-
- splice 1.插入元素
1
2
3
4
5
6
7
8
9
10
11const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// inserts at index 1
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, 'May');
// replaces 1 element at index 4
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "May"]
- splice 1.插入元素
splice 2.刪除元素
1
2
3
4
5var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = myFish.splice(3, 1);
// removed 為 ["mandarin"]
// myFish 為 ["angel", "clown", "drum", "sturgeon"]-
1
2
3
4
5
6
7
8
9
10const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// expected output: Array ["Dec", "Feb", "Jan", "March"] //按照第一個字母順序排列
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4] //是一字串,以第一個數字來排列 依照數字大小排列
1
2
3
4
5
6
7var arr = [1, 30, 4, 2];
arr.sort(function (a, b) {
if (a === b) return 0;
if (b > a) return -1; //不換
return 1; //正數,換位置
})
console.log(arr);
「回傳」與「印出」的差異
- 函式可以透過 return 回傳函式運算完的結果
述程式碼的執行:
1.console.log(add(1, 2))
=> 帶入functoin,console.log(a, b);
=> 印出1,2
2.往下,到return undefined; 然後進入add(1, 2)的回傳值,就會是undefined
1 | function add(a, b) { |
- 以為
add(1, 2)
的回傳值是 3,但不是,那是因為它在裡面 console.log() 所以把結果印出來了。1
2
3
4function add(a, b) {
console.log(a + b)
}
add(1, 2) - 如果真的要有回傳值的話要這樣寫:
1
2
3
4function add(a, b) {
return a + b
}
console.log(add(1, 2))
參考資料: JavaScript 初心者筆記: 函式實際運作 - 回傳值與函式間互相傳遞
,後設鐵人 Day4:請幫我簽個名好嗎?
Immutable 觀念 (不可變)
- 除了物件、陣列以外,其他都是不可變的
- 沒辦法改它,就只能回傳新的
1
2
3
4var a = 'hello';
a.toUpperCase;
console.log(a);
//印出:hello,沒有改變原本變數的內容1
2
3
4
5
6
7
8
9var a = 'hello';
a = a.toUpperCase(); //要回傳給a,把原本的a值蓋掉
console.log(a);
//或是增設一個新變數
var a = 'hello';
var b = a.toUpperCase();
console.log(b);