Javascript偏向弱型別的語言,不需要像Java那樣先指定變數的型態!
/* Java */
String x = "10";
String y = "20";
x = 3; //且不能重新賦指定型態外的值
int result = Integer.parseInt(x) - Integer.parseInt(y); //運算時也必須將型態明確剖析轉換
在javascript裡就不需要事先宣告變數的型態了,相對來說變得很彈性。
/* javascript */
let x = '10';
let y = '30';
let result = y - x; // 20:可以直接做運算,型態會自動轉換
console.log(typeof result); // number
x = 10; //可以直接重新賦予任何型態的值
javascript裡型態的轉換很常發生,像是上述的let result = y - x;就發生了型態的轉換,原本為字串的x與y轉換成了數字(number型態),再看個例子:
let number = 100;
number.toString();
toString是在物件上才有的方法(特性),此時(這裡的number)就會自動使用Number實例來包裹100這個數字,因此才可以操作toString,同樣也是進行了型態轉換,自動轉型。
上面講了些基型值(如string,boolean,number etc...)的轉換,那物件的轉換呢?
let obj = {
value : 10
}
let x = 10;
console.log(x + obj);
基型值
指的是number
、boolean
、string
、null
、nudefined
這些javascript裡的基本型態之值型態的轉換很常發生在運算的時候,在說物件的轉換前,先從基型值的運算說起吧!
使用加號很簡單,直接這樣寫即可
let num = 1 + 2;
console.log(num); // 3
兩個「數字」相加很單純也很簡單
但還有「特殊數字」,什麼是特殊數字呢?Infinity
、-Infinity
、Nan
就是這裡所說的特殊數字,來讓他們相加看看
Infinity + Infinity //Infinity
Infinity + -Infinity //NaN
-Infinity + -Infinity //-Infinity
NaN
的話只要任何一個是NaN
的話,結果就是NaN
10 + NaN //NaN
Infinity + NaN //NaN
那如果有一個是字串呢?
10 + 'String' //?
10 + '10' //?
結果會是10String
在做加號+
運算的時候,有一邊是字串的話會先做字串的串接,所以原是number型態
的10會轉換成字串型態
,再做字串的串接動作,也就是會「自動轉型」
number
、string
、boolean
會使用型態各自的Wrapper(包裹器)包裹後,使用toString()方法轉成字串,而null
、undefined
這兩個特殊小孩就沒有各自的Wapper了,而是使用javascript的String()來轉換成"null"、"undefined"字串。那如果是這樣呢?可以自己思考看看或是試試看!
let x = 100;
let y = 100;
let result = '100 + 100:' + x + y; //?
物件型別的運算就不一樣了,再物件上我們可以使用或是自定義toString
與valueOf
方法來轉換,舉個例子:
let obj = {
valueOf: function() {
return 100;
}
console.log(100 + obj); //200
valueOf
方法,如果回傳的是基型值,javascript就會將基型值轉換成數字(需要的話),並回傳結果。valueOf
方法的話就使用toString()方法,若該方法回傳基型值,javascript將之轉換並回傳。let obj = {
toString: function() {
return 'one';
},
valueOf: function() {
return 100;
}
console.log(100 + obj); //?
結果還是200,也是先套用了valueOf()方法
同樣的上面obj,試試valueOf回傳的不是基型值
valueOf: function() {
return {};
}
結果為'100one',也證實了如果valueOf()回傳的若不是基型值時會套用toString(),再依運算的需求來決定是否需要轉換型態。
再來看看下面這個例子:
console.log({}.toString()); //[Objet Objet]
console.log({}.valueOf()); //{}
會有這樣的結果是因為物件在無定義toString()
與valueOf
的情況下,預設為toString()回傳'[Object Object]'
,而valueOf()回傳this
。
console.log(1 + {}); //?
console.log(1 - {}); //?
物件型別做加減乘除時,都會先套用valueOf方法,也就是object-to-number
primitive-to-string
,也就是會用到wrapper)(不是字串的話),並回傳結果。