給自己看的 JavaScript 系列:
[Week2] 給自己看的 JavaScript 筆記 -運算
[Week2] 給自己看的 JavaScript 筆記
更新紀錄:
2020/07/01 一小時挑戰
2020/07/02 一小時挑戰之延長賽
迴圈
迴圈可用於處理重複進行的事情,最常見的形式為:
while(條件){
指令
}
因此順序為先檢查條件是否為 true ,若為 true 則進入迴圈執行指令,結束後再回到第一行檢查條件,如此往復。
另一種經典的寫法如下:
for(初始值; 條件; 每圈結束後的指令){
指令
}
例如我想要印出一到十,就可以寫:
for (i = 1; i <= 10; i++){
console.log(i)
}
函式
數學上的函式為 f(x) = y
,將 x 輸入進去就可以得到 y 。 JavaScript 中的函式寫法如下:
function 名稱(參數){
指令
return 回傳值 //若沒設定則自動回傳 undefined
其中可以放其他的 function。若要查看函式的特性可以這樣:
function hi(){
return 'hello'
}
console.log(hi) // [finction: hi]
console.log(hi()) // 'hello'
函式也不一定要取名字,例如:
function transform(arr, func){
var result = []
for(i = 0; i < arr.length, i++){
result = func(arr[i])
}
return result
}
console.log(transform([1, 3, 5], function(x){
return x * 2
}) //[2, 6, 10]
參數和引數
fuction add(a, b){
return a + b
}
console.log(add(2, 3)) // 5
上面例子中, a 和 b 就是函式的 參數
,而 2 和 3 則是 引數
。可以在函式中使用 console.log(arguments)
查看引數。引數會以物件形式出現,例如{'0': 2, '1': 3}。
函式的特性
函式再讀取引數時,對電腦來說是先複製一份才執行,因此所有變動都不會影響到外面。例如:
var n = 10
function double(x){
return x * 2
}
double(n) // 20
console.log(n) // 10
不過物件和陣列可能會改變,和記憶體位置有關,可看本篇文章最後的「其他觀念」。
return
如果不需要知道結果(比如說只是要 console.log 某個東西)可以不用 return,此時會預設 return undefine 。
另外, return 後的東西都不會執行。
內建函式
數字相關
寫法 | 用途 | 範例 |
---|---|---|
Number(str) | 字串轉數字 | var num = Number('11') //11 |
parseInt(str, 進位制) | 字串轉整數,通常使用十進位 | var num = parseInt(2, 10) //10 |
parseFloat(str) | 字串轉小數 | var num = parseFloat('3.2') //3.2 |
num.toFixed(幾位) | 取到小數點後幾位四捨五入 | var num = 2.78.toFixed(1) //2.8 |
Number.MAX_VALUE | 顯示 JavaScript 能記憶最大的數,再大會不精準 | var max = Number.MAX_VALUE //1.7976931348623157e+308 |
Number.MIN_VALUE | 顯示 JavaScript 能記憶最小的數,再小會不精準 | var min = Number.MIN_VALUE //5e-324 |
Math.PI | 圓周率 | var pi = Math.PI //3.141592653589793 |
Math.ceil(num) | 無條件進位 | var ceil = Math.ceil(10.1) //11 |
Math.floar(num) | 無條件捨去 | var floor = Math.floor(10.1) //10 |
Math.round(num) | 四捨五入法 | var round = Math.round(10.1) //10 |
Math.sqrt(num) | 開根號 | var sqrt = Math.sqrt(144) //12 |
Math.pow(num, times) | num 的 times 次方 | var pow = Math.pow(3, 3) //27 |
Math.random() | 隨機生產 0 <= n < 1 | var pow = Math.random() //0.84 |
以上常數皆用大寫表示。
數字轉字串有兩種做法:
var a = 12
a = a.toString() //'12'
var b = 43
b = b + '' //'43',因為字串加數字等於字串
字串相關
大小寫
概念:以下所有的位置都是由 0 開始計算,而非 1 。
str.toUpperCase(a)
:將str的第a個字(從零開始)轉為大寫。
str.toLowerCase(a)
:將str的第a個字(從零開始)轉為小寫。
var a = 'hello'.toUpperCase(2) //'heLlo'
var b = 'HELLO'.toUpperCase(0)` //'hELLO'
ASCII
ASCII 是將字串用數字存起來的形式,每個字母都可以對應到一個數字,且大小寫不同,例如 A 對應到 65 、 B 對應到 66 、 a 對應到 97 。
str.charCodeAt(a)
:得到字串第 a 位置的 ASCII。
String.fromCharCode(num)
:得到數字 num 在 ASCII 上對應到的字母。
運用 ASCII 可將數字轉大小寫,例如:
var str = 'a'
var temp = str.charCodeAt(a) //97
temp -= 32 //65
str = String.fromCharCode(temp) //'A'
若將數字比大小,則是轉換為 ASCII 再比。因為字母的 ASCII 有連貫,因此若要測試字母是否為大寫,可以用 str >= 'A' && str <= 'Z'
。
搜尋和取代
str.indexOf('key')
: key第一個字在str的位置。若有兩個以上,則回傳最前面的。若找不到key,會回傳負數。
str.replace('key', new)
:將 str 中的 key 換成 new。一樣只會換第一個,若想要全部替換可使用正規表達式。詳細可參考 MDN 。
var a = 'hello'.indexOf('el') // 1
var b = 'hello'.replace('l', 'i') // 'heilo'
其他
str.spilt(a)
:以 a 為標準將字串拆開,並變成陣列。
str.strim()
:去掉字串前後的空格。
str[i]
:叫出字串位置 i 的字。
var a = 'hello world'
var spilt = a.spilt(' ') // ['hello', 'world']
var b = a[4] //'o'
陣列相關
arr.join(a)
:用 a 將陣列接起來,回傳字串。
var a = ['hello', 'i', 'am']
a = a.join('!') // 'hello!i!am'
arr.map(function)
:讓串列中每個元素都跑過函式。
var a = [1, 3, 5, 7, 9]
a = a.map(function(i){
return i+1
})
console.log(a) // [2, 4, 6, 8, 10]
arr.filter(function)
:串列通過函式回傳 true 的會留下。
var a = [1, 2, 3, 4, 5]
a = a.fliter(function(i){
return i % 2 === 0
})
console.log(a) // [2, 4]
只要還是陣列, .map 和 .fliter 可以一起使用,也可以無限往後加。
arr.slice(a, b)
: 回傳陣列的第 a 個元素到第 b-1 個數。
var a = [1, 2, 3, 4, 5]
a = a.slice(2, 4) //[3, 4]
arr.splice(start, remove, new)
:在第 start 的位置,刪除 remove 個元素,並插入 new 為新的元素。(會改變陣列本身)
var a = [1, 2, 3, 4, 5]
a.splice(1, 0, 9) //[1, 9, 2, 3, 4, 5]
a.splice(3, 1, 'hi') //[1, 9, 2, 'hi', 4, 5]
arr.sort(function)
:將陣列的元素由小排到大。
var a = ['apple', 'zipper', 'cute']
a.sort() //['apple', 'cute', 'zipper']
var b = [22, 18, 9]
b.sort() //[18, 22, 9]
上面數字的排序只是看最前面的數字,要真正幫數字排序可使用函數。概念為若回傳值 <= 0 不調換,但若 > 0 則互換。詳細可參考MDN因此若要由小排到大,可用:
b.sort(function(a, b){
return a - b
})
此時若要由小排到大,改成 b - a
即可。
arr.reduce(function)
:可用於累積加總,例如求陣列總和:
var a = [22, 18, 9]
b.reduce(function(acc, cur){
return acc + cur
})
其實就是將上次執行的成果(如 22 + 18)存到 acc ,再執行下一個( acc + 9)。這個方法可以避免外面再多存一個初始值。
其他觀念
詳細觀念可參考:
從博物館寄物櫃理解變數儲存模型
Immutability 為何重要?淺談 immutable.js 和 seamless-immutable
物件在記憶體內儲存的方式
可先看看這幾題:
var a = ([] === [])
var b = ([1] === [1])
var c = ({} === {})
var d = ({a:1} === {a:1})
以上四個全部都是 false!
因為物件儲存的方式是先將物件放再記憶體位置內,再紀錄記憶體位置。左邊的 []
和右邊的 []
其實是存在不同記憶體位置,等式判斷時是看記憶體位置,因此才會得出 false。
另外也有這種狀況:
var a = [1]
var b = a
b[1] = 2
console.log(a, b) // [1,2], [1,2]
此時因為 b 的記憶體位置直接對應到 a 的,因此修改到 b 的內容就會修改到 a。但如果:
var a = [1]
var b = a
b = [1, 2]
console.log(a, b) // [1], [1,2]
上面直接將 b 指定到新的記憶體位置,因此 a 不會受到影響。
Immutable 不可變
不可變是指在創建變數、賦值後便不可改變,若對其有任何變更(例如:新增、修改、刪除),就會回傳一個新值。例如:
var a = 'hello' //放在記憶體 0x01
a = 'change' //開新的記憶體 0x02
a.toUpperCase(0) // 只有 return 沒有改變 a
console.log(a) // 'change'
所有的字串都是不可變的,有些內建函式可以改變陣列,因此使用前可先看 說明書 才不會產生奇怪的 bug。
心得
最後花了總共三個小時才完成這篇(躺)果然記筆記吃力不討好,不過相信未來的我會感謝自己的(?)