[Week2] 給自己看的 JavaScript 筆記 - 迴圈、函式、其他觀念


給自己看的 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。

心得

最後花了總共三個小時才完成這篇(躺)果然記筆記吃力不討好,不過相信未來的我會感謝自己的(?)

180天成為工程師






Related Posts

[16] 值 VS. 參考

[16] 值 VS. 參考

Day5 跟一般的指令可不一樣啊!跟我所認識的指令不同啊!

Day5 跟一般的指令可不一樣啊!跟我所認識的指令不同啊!

3. 優美地定義 React 型別

3. 優美地定義 React 型別



Comments











Sponsored