#兩大類型別圖:
#原始型別(primitives):
#物件型別:
#如何判斷是不是物件(型別)?
- 物件型別特質:可以自由擴增屬性。
//物件
const obj = {};
obj.age = 32;
console.log(obj);
---- console區 ------
{age: 32}
//陣列 PS:實戰/平常中千萬不要這樣寫!!!!
const arr = [];
arr.age = '他今年滿18';
arr.push(18);
console.log(arr);
---- console區 ------
[18, age: '他今年滿18']
//函式 把函式作為物件使用(實戰中可能見到)
const fn = function () {
};
fn.mySlogan = '我一個詭異的函式物件';
console.log(fn);
---- console區 ------
//通常console.log無法看見函式內部內容
ƒ () {
}
---- console.dir()區 ------
這個方法可以看見物件型別中的內容
ƒ fn()
mySlogan: "我一個詭異的函式物件"
arguments: null
caller: null
length: 0
name: "fn"
//原始型別只有純值,無法拓增屬性
const num = 1;
num.mySlogan = '今天是好天氣';
console.dir(num);
---- console.dir區 ------
1
dir使用時機?25.00
型別方法在哪裡?
原始型別的方法來自於-boxing-原始型別包裹物件:
console.dir(String) //所有字串 數字型別方法都存在這 ---- console.dir區 ------ ƒ String() 可以點選開發人員工具中顯示出的prototype:String屬性
運作原理new operator://實戰千萬不要這樣寫
- 以下由new來創建(物件):
let str = new String(' 我是特別的 ');//這會是一個物件 console.log(str) console.log(str.trim()) ---- console區 ------ String {' 我是特別的 '} 我是特別的
- 以下由new來創建(物件):
let str2 = new String(' 我是特別的 ');
console.log(typeof str)
console.log(str == str2)
---- console區 ------
Object
false
//但這明明是兩個一樣的東西字串>純值>>變質了
-----------------------------
記住:str中存的原來是字串>原始型別>純值,無法拓增屬性,但是.....
str.myName = '加入了怪東東'
console.log(str)
---- console區 ------
String {' 我是特別的 ', myName: '加入了怪東東'}
#型別轉換(JS型別可以自由轉換)
#顯性轉換
1-1:boxing-原型型別包裹物件 Number,String
let price = 100; //number console.log(String(price)) //string console.log(BigInt(price)) //bigint console.log(Symbol(price)) //symbol(100)
1-2:原型方法(要注意原型鍊中有沒有該方法/有沒有原始型別包裹物件)
console.log(price.toString()) //string !!要注意原型鍊中有沒有該方法/有沒有原始型別包裹物件 console.log(undefined.toString()) //TypeError
1-3:數值型別相關方法
console.log(Number('100元')) //NaN console.log(Number.parseInt('100元')) //100 console.log(parseInt('100元')) //100 因為在window全域物件下也有一個parseInt()的方法 console.log(window.parseInt === Number.parseInt) //true
3:正負運算子,正負一元運算子(一定會轉型成number)
//二元運算子的例子:轉型成string console.log(1 + '1') //二元運算子轉型為string '11' >>> `+`是運算子 >>> 1是一個運算元 >>> '1'是一個運算元 這是二運算元
//ㄧ元運算子的例子:轉型成number console.log(+ '1') //會轉型成number 1 >>> `+`是運算子 >>> '1'是一個運算元 這是一運算元
//ㄧ元運算子的例子:轉型成number console.log(+true) //會轉型成number 1
//ㄧ元運算子的例子:轉型成number console.log(+'50元') //NaN NaN的型別是number
2-2:邏輯 NOT 運算子(會轉型成boolean)
console.log(!true) //false
console.log(!false) //true
console.log(Boolean(0)) //先轉型成false
console.log(!0) //true 因為0是falsy value
console.log(Boolean('1')) //true
console.log(!'1') //false
console.log(!!'1') //true
隱性轉換(盡量不要去作隱性轉換)
- 運算子(二元運算子)
- 規則1:前後運算元,如果其中一個為字串型別,+就會被視為“字串運算子”
- 規則2:前後運算元,如果無法轉成原始型別(那就是物件型別),+也會被視為“字串運算子”
- 規則3:上述情況以外,+會被視為“算數運算子”
console.log(100+100) //200 算數運算子 console.log('我是'+'無敵') //'我是無敵' 字串運算子
- 運算子(二元運算子)
練習:
console.log(1+'1') //"11" string +字串運算子
console.log(1+true) //2 number +算術運算子
console.log(1+ {}) //1[Object object] string +字串運算子
console.log(String({})) //[Object object]>>算數中,所有物件都是用String({})去做轉型所以會是 [Object Object]
console.log(1 + []) //"1" string +字串運算子
console.log(1 + [1,2,3]) //"11,2,3" string +字串運算子
console.log(1+ {a:1}) //1[Object Object]
特例:bigInt無法和其他型別/數字直接作轉換
console.log(1 + 1n) //error
特例:symbol()
console.log(1 + symbol(1)) //cannot a symbol value to a number
console.log( '1' + symbol(1)) //cannot a symbol value to a string
console.log({} + symbol(1)) //cannot a symbol value to a string
特例:bigInt無法和其他數值直接作轉換
console.log(1 + 1n) //error
- 算術運算子(- / * )
### 例外狀況 BigIntconsole.log(1 - '1') //0 number console.log(100 * true) //100 number console.log(100 - true) //99 number
console.log(1n * 100);
其他類型比較
console.log([100] * 100); //10000 number
console.log([100,1] * 100);// NaN
//陣列轉型
console.log([100].toString());
console.log([10, 0].toString()); // 10 ,0
console.log(Number([10, 0].toString())); // NaN
型別比較
1.寬鬆相等:值相等,型別 不需要
console.log(1 == '1'); //true
Number Strung Boolean 這三個進行比對時,都會以Number進行轉型
console.log("1" == true) // true console.log(1 == "1") // true console.log("0" == false) // true
null,undefined 不轉型(都是false),但null與undefined兩者相比都是true
cosole.log(null == 0) //false cosole.log(null == '') //false cosole.log(null == false) //false console.log(null == undefined) //true console.log(null == null) //true console.log(undefined == undefined) //true
- 物件與非物件比對:物件與其他類型比對時,會透過“boxing包裹物件”將物件轉為相同型別
//使用原始型別包裹物件作轉型console.log([0] == 0) //true console.log('[object object]' == {}) //true 因為String({}) [object object] console.log(['a'] == 'a') //true
- 1:布林採用Number轉型
console.log([] == false); //true Number([]) >> 0 >>falsy value console.log([1] == true) //true console.log([2] == true) //false
- 2:陣列轉數值,會先toString()再套用Number
- 3: 例外冷門:
let sym1 = Symbol(1) let sym2 = Symbol(1) console.log(sym1 == sym2) // false
- 例外:Bigint,轉為數學值,沒有NaN,沒有小數點,沒有最大值其他概念與Number接近
console.log(Number.MAX_SAFE_INTEGER) //9007199254740991 console.log(9007199254740991 == '9007199254740991') //true console.log(9007199254740993 == '9007199254740992') //true >>>已經超過最大安全數值,因此比對結果有問題 console.log(9007199254740993n == '9007199254740992') //false 超過安全數值之後,有加入BigInt相對在比對上是穩定的 console.log(9007199254740993n == '9007199254740993') //true 超過安全數值之後,有加入BigInt相對在比對上是穩定的 console.log(100n * 100n) //10000n
2.嚴格相等:值 與 型別 完全相同 (開發使用這個)
console.log(1 === '1'); //false
3.嚴格相等有例外狀況
//false版
console.log(NaN === NaN); //false
console.log(undefined === null); //false
console.log({} === {}); //false
console.log([] === []); //false
console.log(new Number(0) === new Number(0)); //false
原理是記憶體位址指向不同
//true版
console.log(+0 === -0); //true
console.log(Infinite === Infinite); //true
真假值(待補充)
筆記來源:
- <js直播工程師養成班-六角學院>
- <javascript 核心篇-六角學院>