JavaScript #1 — 運算子、運算式、值與型別、變數

Thomas Hung
Thomas 學習筆記
10 min readMay 9, 2020
Photo by KOBU Agency on Unsplash

變數(Variables)

變數是儲存值 (value) 的容器,它可用來與運算子做運算式,這裡要注意JavaScript 是弱型別的語言,意指宣告變數並賦值後仍可改變值的型別

// 使用 let 宣告變數並賦值let a = 'ABC'  //String 字串型別
a = 123 //Number 數字型別

在 JavaScript 中,宣告變數時有一定的規則,必須以英文字、錢字號 $、底線 _ 為開頭,之後可以是 英文字、錢字號 $、底線 _ 、數字 (0~9),不可以使用關鍵字保留字。也可以使用中文字來宣告變數,但編碼時可能會成亂碼。

在 JavaScript 中須注意的是宣告變數時,有區分大小寫,也就是說 let namelet NAME 是兩個不同的變數。

let a_1 = "ABC" //ABC 這是合法的let 1_a=123  //SyntaxError 這是不合法的let obj = {
this: "abc",
}
obj.this //abc 這是合法的let name = "abc" //'abc' 有區分大小寫let NAME = "ZXC" //'ZXC' 有區分大小寫

在 ES6 之前宣告變數只有 var 存在著 提升 (hoist 這部份之後再說明) 特性,在作用域中宣告 var變數會被提升到最頂端,它用來區分存取範圍就是函式作用域(Function Scope)並稱為區域變數,函式作用域以外的範圍都是全域變數

ES6之後除了 var 宣告變數以外,新增 letconst ,稱為變數與常數( 常數 在 ES6 中的定義是constant variable 固定的變數),可以使用作用域範圍 {} (使用大括號)做區分。

在 JavaScript 是弱型別的語言,代表宣告的變數本身是沒有型別,只有在值 (value) 與 物件本身 才有型別,變數是用來存取 值 (value) 與 物件的參考。

//透過 var 宣告變數 x ,但未賦值時存取 x 會出現 undefined
var x
//透過 let 宣告變數 y,但未賦值時存取 y 會出現錯誤 ReferenceError
let y

在這裡要注意的是,如果沒有透過 varletconst 宣告變數時,會自動變成全域變數 (之後在作用域 Scope 介紹)

在使用宣告常數 const 時,代表這個變數是不可以再改變它的值,如改變會出現錯誤。

const PI = Math.PI;PI = 1 //TypeError: Assignment to constant variable.

變數的生命周期

在 ES6 之前宣告變數只有 var ,用來區分存取範圍就是 函式作用域(Function Scope),在這裡面宣告的變數就稱為區域變數,如下範例 :

var globalScope = '全域'function showVal() {
var blockScope = '區域'
return blockScope
}
console.log(showVal()) //區域console.log(globalScope) //全域

var的宣告變數 blockScope 的生命周期,就存於 函式作用域(Function Scope)之內,全域環境並不能存取這個變數。

另外,在ES6中新增 letconst ,稱為變數與常數( 常數 在 ES6 中的定義是constant variable 固定的變數),新增可以使用區塊作用域 (Block Scope,使用大括號 {})作區分。如下範例 :

let block = "全域"if (true) {
let block = "區域"
}
console.log(block) //全域

let 的宣告變數 block 的生命周期,就存於 區塊作用域 (Block Scope,使用大括號 {})之內,全域環境並不能存取這個變數。

變數的生命周期會再之後的 範疇 (Scope)中詳細介介紹。

變數的資料型別

在 JavaScript 中,變數沒有型別,值 (value) 才有型別,型別區分為 基本型別 (Primitive Type) 與 物件型別 (Object Type) 二種。

基本型別 :

除了以上的是基本型別,以外都是物件,例如 : 陣列 Array日期 Date函式 Function物件 ObjectMath

我們可以用 typeof 來檢測資料型別是什麼。

typeof "abc" //stringtypeof 123 //numbertypeof null //objecttypeof undefined //undefinedtypeof function () {} //functiontypeof {} //objecttypeof [] //objecttypeof true //booleantypeof NaN //numbertypeof Symbol() //symbol
  • 這裡會發現有不一樣的地方,null 會回傳 object 這是個 bug 如果修正這個會造成很多網站不能使用。
  • 雖說 function(){} 會回傳的是 function ,和 Array [] 回傳的是 object 不一樣,但它們都是物件,函式是可被呼叫的物件。
  • NaN 代表無效的數字 (not a number),但它還是數字喔,回傳還是 number,不要被字面給搞混了,它的特性是與任何數字作運算都會得到NaN ,它不大於、不小於、不等於任何值,包含自己。可以參考 : JavaScript 運算式與運算子 & 型別轉換筆記一

null 要如何被檢測出來呢?有想到嗎!提示 : JavaScript Boolean (布林值) 筆記 ,那來看看吧

let data = nullif (!data && typeof data === "object") console.log("我是 null")!data 判斷是否為 false ; typeof data 判斷是否為 object ,這就能判斷出來。

在這裡再次強調 typeof檢測變數的值 (value),因此只有值才有型別

在這裡還有另一個奇怪的地方是 NaN 不是個數字(not a number),但如用 typeof 來檢測時為 number 。它作任何運算都是 NaN ,並且本身不等於本身。

typeof NaN //number  NaN === NaN  //false

那問題來了,要如何檢查這個變數是不是等於 NaN ?這時候可以透過 Number.isNaN() 方法來檢查。參考 : JavaScript Number (數值)-學習筆記

Number.isNaN(NaN) //trueNumber.isNaN(0/0) //trueNumber.isNaN(123) //falseNumber.isNaN('abc') //falseNumber.isNaN(undefined) //falseNumber.isNaN([]) //falseNumber.isNaN({}) //falseNumber.isNaN("NaN") //false

如何判別是否為陣列

在物件型別中分別有 : 陣列 Array日期 Date函式 Function物件 ObjectMath

那要如何判斷是否為陣列,一開始我們用 typeof 檢測 陣列會是 object 的物件,那如果要確定它是否為陣列呢?在這裡介紹陣列中的方法 Array.isArray()參考 : JavaScript Array (陣列)-學習筆記一

Array.isArray([1, 2, 3])  //trueArray.isArray(new Array()) //trueArray.isArray('abc')  //falseArray.isArray(null)   //falseArray.isArray(undefined)       //falseArray.isArray({ obj: 'abc' })  //false

null 與 undefined

這兩個有什麼不一樣呢?雖然這兩個在布林強制轉值的型態是 false ,但兩者之間在意義上是有差異的。

  • null : 代表曾宣告的變數之前可能有值或沒有值,但現在是沒有值。通常指的是不存在或無效的物件。
  • undefined : 代表此變數已宣告但是未賦值。
let xlet y = nullconsole.log(x) //undefinedconsole.log(y) //null

由以上的例子,還可以透過 Number() 來說明兩個的差異性 :

console.log(Number(null)) //0console.log(Number(undefined)) //NaN

運算子 ( Operators )、運算式 ( Expression )

在 JavaScript 語法可以分為二種,敘述句(Statement)與運算式(Operator)。

  • 敘述句簡單說明就是宣告變數、賦值、判斷式等等。
  • 運算式最大的不同就是它會產生一個值。如 :
let a = 1 * 2  //在等號的右邊就是運算式a  // 2 

運算子(Operators)

對變數或值在這之間作運算式的符號,就是運算子。如 :

let a = 1
let b = a + 2
// =+ 都是運算子

運算子的類型大致上可以分為以下幾種 :

  • 賦值運算子 : 就是將等號運算子 = 來執行賦值,並將等號右邊的結果放入左邊的變數中,例如 a = b + 1 就是將 b + 1 放入 a 變數中。
  • 比較運算子 : 比較兩邊運算元的關係,運算子有 大於 >、小於<、小於等於< =、大於等於> =,並將比較結果回傳 truefalse ,運算元可以是 數值 、字串、表達式 、物件等。
  • 算數運算子 : 就是大家知道的四則運算,如加+、減-、乘* 、除 / 、取餘數 %以及指數 **與遞增++和遞減--的運算,如 a + 1
  • 位元運算子 :轉化為 32 bits的整數,並以二進位(0、1)的形式做處理,並將超過32 bits的整數捨棄多餘位元,運算後回傳數值。如 8二進制表示法為 1000 , 5二進制表示法為 0101 ,做運算 1000 & 0101 結果為 0000 並回傳數字 0
  • 邏輯運算子 : 使用 and && 、or ||、not ! 做邏輯運算,如 12 && 'abc' ,數字12 強制轉型布林值 true ,字串 'abc' 強制轉型布林值也是 true ,所以回傳 'abc'
  • 條件(三元)運算子 : 運算式有兩個運算元的值,且一個運算子作為條件,語法 條件 ? 值1 : 值2 ,當條件成立時回傳 值1 否則回傳 值2,如 ( age < 18 ) ? 未成年 : 成年 ,成立時回傳未成年 ,否則回傳成年
  • 逗點運算子 : 讓逗號可以分隔運算式(由左至右),並且回傳最後的運算式的值,如 for 迴圈 ,範例 :for (let i = 0, j = 10; i < 10; i++, j--) {...}

可以參考以下的筆記!!

JavaScript 運算式與運算子 & 型別轉換筆記一JavaScript 運算式與運算子 & 型別轉換筆記二

參考 :你懂 JavaScript 嗎?#2 暖身 (๑•̀ㅂ•́)و✧ Part 1 — 運算子、運算式、值與型別、變數、條件式、迴圈重新認識 JavaScript: Day 03 變數與資料型別

以上是我對JavaScript #1 — 運算子、運算式、值與型別、變數 學習筆記 😉。

***如果有任何想法,也歡迎留言與我分享~***

--

--

Thomas Hung
Thomas 學習筆記

when you feel like quitting,think about why you started.