tags: JavaScript 基本運算 邏輯運算 短路特性 位元運算 位移運算 object array

JS101 筆記

Chrome debugger

在程式碼中打進 debugger 然後放進 chrome 的 developer tool 裡面,程式就會停在 debugger 那一行,然後就可以在 source 裡一行一行檢視。

另外如果我們在 souces 裡點一下數字就可以設下中斷點,也可以幫助debug。

console.log

// 參考《你所不知道的JS:導讀,型別與文法》

語法 用途
console.log(b) 在控制台 log 進資料(可印出內容)
  1. log(b)是一個 call function
    - 把 b 這個變數的值交給被 call 的 funcion(在這裡是log)
    - 也就是這裡是 log (取) b 這個變數的值的意思

  2. console. 是一個 object reference(物件參考),參考到 log(..) 所在的物件。
    - 其中,.是一個運算子
    - 也用來進行物件特性(object properties)的存取

運算子

// 參考《你所不知道的JS:導讀,型別與文法》
運算子分為以下幾類:

  • assign
    • =
  • math
    • +, -,*,/,%
  • 複合指定
    • +=, -=, etc.
  • 遞增或遞減
    • ++, --
  • object properties 的存取
    • .
  • 相等性
    • ==, ===,!=,!==
  • 比較
    • <, >,<=, >=
  • 邏輯
    • &&(and) , \\ (or), !(not)

value and type

// 參考《你所不知道的JS:導讀,型別與文法》

  • number //42
  • string //"42"
  • boolean // ture, false
  • array
  • function
  • object

Type coercion

//參考Type coercion

  • explicit type coercion (明確的強制轉型)
    • 又叫做 type casting
    • 用內建函式轉型 coerce
    • 由寫程式的人要求執行轉型
      - 如 Number(value)
  • implicit type coercion (隱含的強制轉型)
    • JavaScript 自己進行 coerce

基本運算( math 和遞增、遞減)

語法 用途 用例 注意點
+ 加號 1 + 2 // 3 前後空格
- 減號 3 - 2 // 1 前後空格
* 乘號 2 * 3 // 6 前後空格
/ 除號 4 / 2 // 2 前後空格
% 取餘數 10 % 3 // 1 前後空格
++ 遞增 i++ eslint 不接受
i++ 會先跑完整句才加, ++i 會先加完再跑整句
遞減 i++ eslint 不接受
i 會先跑完整句才減, i 會先減完再跑整句

邏輯運算

語法 用途 用例
pipe * 2 or ture pipe * 2 false // ture
* 這裡不支援pipe 符號
&& and ture && false // false
! not !ture // false
!false // ture

turth table

A B A && B A or B !A
ture ture ture ture false
ture false false ture fals
false ture false ture ture
false false false false ture

邏輯運算短路特性

  • 跑到有結果就會回傳
  • 最後跑到哪一個就回傳那一個
輸入 回傳 解釋
3 or 10 3 在跑到 3 時已確定是 ture,所以直接回傳 3
false or 10 10 跑到 10 才確認是 ture,所以回傳 10
0 or false 10 0 可以就當作是 false
3 && 10 10 在跑到 10 時才確定是 ture,所以回傳 10
false && 10 false 跑到 false 就確定是 false 所以回傳 false

小筆記
//可以直接在 CLI 輸入 node 寫程式

位元運算

位移運算 <<>>

把用二進制系統儲存的數據整個往左或往右移一位

輸入 輸出
10 << 1 20
1 << 10 1024
  • 在二進制整個數據往左移>>一位其實會使數據乘以 2
  • 反之,如果是往右移 <<,則會除以2(有小數的部分會被消失不會進位)
  • 如果位移的位元太多,會有 overflow 的問題

位元運算

  1. 先把東西變成二進位
  2. 對每一個位元運算

在 JavaScript 中

語法 用途 輸入 輸出 二進位
& and 10&15 10 1010 &
1111 ==
1010
pipe or 10 or 15 15 1010 &
1111==
1111
^ xor 2 ^ 4 6 1010 &
1111 ==
0101
! not !15 -16 00001111
1111110000
  • xor: 兩個東西一樣 -> 回傳 0
    兩個東西不一樣 -> 回傳 1

用位元運算判斷奇偶數

輸入 輸出 理由 推論
A & 1 0 A 的最後一個位元是 0 A 是偶數
A & 1 1 A 的最後一個位元是 1 A 是奇數

變數

  • 宣告變數
statement 用法 說明
var 宣告變數 ES5以前的舊用法會有覆蓋和洩漏的問題
let 宣告變數 ES6之後的語法
const 宣告常數 建議命名全大寫
宣告之後就不會再被重新賦值
  • 如果宣告變數之後沒有賦值,變數就數會是 undefine

  • 如果 log 的對象沒有被宣告,就會出現 Not define 警告

  • 變數命名

    • 最常見:駝峰式 newFunction
    • 不合法:
      • 用數字開頭
      • 和內建函數、保留字同名
    • 盡量用語意化的詞
      • 讓後面的自己看得懂

變數型態

  • 型態

    • primitive
      • number //42
      • string //"42", '42'
      • boolean // ture, false
    • object
      • array
      • object
      • null 這是一個Javascript 歷史久遠的 bug
    • function
    • undefine
  • 查看型態

    • 用內建函式typeOf
    • 像是 console.log(typeOf "32") // string

Object

  • a computed value(複合值)

  • 持有一些 properties(特性;具名的位置)

  • 格式:

obj = {
key1 : value1,
key2 : value2 
}
  • 存取物件可以使用兩種方式:
    • dot notatation
      • obj.property運算子存取 property
    • bracket notation
      • obj[property]存取 property
  • property 裡面放 array, object, function 都可以,放什麼都可以

array

  • object 的子項目
  • 可以想像成是以 index 取名的object
  • 只能存相似的資料
  • 內建函式
語法 說明
.length 陣列長度
.push 把 value 放到陣列最後一項

變數運算

  • 注意 type 問題

    • 例如 number + string 時,number 會被 coerce 成 string
  • 可以用兩種內建 function 強制把srtring 轉型成 number

    • Number() //轉型為數字
    • parseInt(number, 10) //逗號後面的數字是進位數(10進位)
  • 浮點數誤差

    • 電腦沒辦法把小數存得很精準
    • 所以會發生 0.1 + 0.2 == 0.3 出來是 false 的狀況

相等性

// 參考《你所不知道的JS:導讀,型別與文法》
JS 的 4 個 equality operators:

符號 說明
== 允許 implicit coercion 的相等性檢查
=== 不允許 implicit coercion 的相等性檢查
!= 允許 implicit coercion 的不等性檢查
!== 不允許 implicit coercion 的相等性檢查

//Equality comparisons and sameness

// ES5 規格第11.9.3節相關implicit coercion 轉換優先順序 :
The Abstract Equality Comparison Algorithm
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

  1. If Type(x) is the same as Type(y), then
    1. If Type(x) is Undefined, return true.
    2. If Type(x) is Null, return true.
    3. If Type(x) is Number, then
      1. If x is NaN, return false.
      2. If y is NaN, return false.
      3. If x is the same Number value as y, return true.
      4. If x is +0 and y is −0, return true.
      5. If x is −0 and y is +0, return true.
      6. Return false.
    4. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
    5. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
    6. Return true if x and y refer to the same object. Otherwise, return false.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. If Type(x) is Number and Type(y) is String,
    return the result of the comparison x == ToNumber(y).
  5. If Type(x) is String and Type(y) is Number,
    return the result of the comparison ToNumber(x) == y.
  6. If Type(x) is Boolean,
    return the result of the comparison ToNumber(x) == y.
  7. If Type(y) is Boolean,
    return the result of the comparison x == ToNumber(y).
  8. If Type(x) is either String or Number and Type(y) is Object,
    return the result of the comparison x == ToPrimitive(y).
  9. If Type(x) is Object and Type(y) is either String or Number,
    return the result of the comparison ToPrimitive(x) == y.
  10. Return false.

Conditionals 條件式

if/else statement

syntax:

if(conditional){ statement; } else { statement; }

switch case

syntax:

switch(varibleName) { case 1: statement break case 2: statement break case 3: statement break }

ternary 三元運算子

syntax:

condition ? trueAnswer : wrongAnswer

範例:

var score = 60 var message = '' message = score >= 60 ? 'pass' : 'fail'

迴圈

do while

syntax:

do{ statement; } while (conditional)
  • continue 直接跳到下一圈(細節待補)
  • break 跳出迴圈(細節待補)

while 迴圈

while (conditional){ statement; }
  • do..while 和 while 差別在於
    • while 會先做 conditional test 才進入第一次 iteration
    • do..while 則會先執行第一次 iteration 才會進行 conditional test

for

for(conditional){ statement; }

例如:

for(var i = 0; i <= 9; i ++){ console.log(i); } //0 1 2 3 4 5 6 7 8 9

function 函數

// 部分參考《你所不知道的JS:導讀,型別與文法》

  • 可重複使用的一個具名片段
  • 也可以用來將相關的程式碼組織成具名的集合
  • 可以藉由名稱來 call function
    • call function 時要包含()
    • 例: console.log(functionName())
    • 不然就會印出他是一個 function
    • 函式參數命名時盡量用有語意的字當參數增加可讀性
  • 需要時可用 return 來回傳值
    • 可以傳任何東西,包含物件
    • 注意 return 後面不可以空白,不然會是 undefine

anonymous function 匿名函式

  • function 的參數也可以是一個 function
    例:
function transform(arr,transformFunction){ let result = [] for(var i = 0; i < arr.length; i += 1){ result .push(transformFunction(arr[i])) } return result } console.log( transform([1, 2, 3], function(x){ return x * 2 }) )
  • 此時的 transformFunction 就是一個 anonymous function 匿名函式

Parameter (參數)和 argument (引數)

function transform(arr,transformFunction) transform([1, 2, 3], function(x){ return x * 2}

這裡的 arr 就是 parameter (參數), [1, 2, 3], function(x)就是 arguments (引數)

  • 可以用 console.log(arguments[0])來 log 出第 0 個argument
  • arguments 是一個 object 但是是一個 Array-like 的物件

function 傳參數機制

  • 用 dot notation 的時候會改到外面的

return

  • 不需要知道結果的
    • 就不需要 return
    • call function 時電腦不會得到回傳值
    • 此時 return value 等於 undefine
  • 會需要知道結果的
    • 需要 return
  • 在 function 中,電腦一遇到 return 就會立刻回傳,然後跳出function,所以在 return 後面的程式碼就不會被執行。

Number 內建函式

// 待補

string 內建函式

// 待補

Immutable values

  • 除了 object(包含 array) 之外,無法用 property accessor 如 dot notation 來改變變數的value。
  • 需要用 = 來重新賦值才會被存下來
  • 反之,在 object 裡用內建函式的 dot notation 進行操作,是會改到 property 的內容的