iT邦幫忙

1

【Javascript筆記】物件-型態轉換

有些話先說一說:

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);
  • 基型值指的是numberbooleanstringnullnudefined這些javascript裡的基本型態之值

關於型態轉換

型態的轉換很常發生在運算的時候,在說物件的轉換前,先從基型值的運算說起吧!

加號(+)

使用加號很簡單,直接這樣寫即可

let num = 1 + 2;
console.log(num); // 3

兩個「數字」相加很單純也很簡單
但還有「特殊數字」,什麼是特殊數字呢?
Infinity-InfinityNan就是這裡所說的特殊數字,來讓他們相加看看

  • 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會轉換成字串型態,再做字串的串接動作,也就是會「自動轉型

  • numberstringboolean會使用型態各自的Wrapper(包裹器)包裹後,使用toString()方法轉成字串,而nullundefined這兩個特殊小孩就沒有各自的Wapper了,而是使用javascript的String()來轉換成"null"、"undefined"字串。

那如果是這樣呢?可以自己思考看看或是試試看!

let x = 100;
let y = 100;
let result = '100 + 100:' + x + y;  //?

物件型別的運算

物件型別的運算就不一樣了,再物件上我們可以使用或是自定義toStringvalueOf方法來轉換,舉個例子:

let obj = {
    valueOf: function() {
        return 100;
    }
console.log(100 + obj);  //200

當需要轉換成數字時,先試valueOf()方法 object-to-number

  • 物件型別的運算(加減乘除etc...),會先使用套用物件的valueOf方法,如果回傳的是基型值,javascript就會將基型值轉換成數字(需要的話),並回傳結果。
  • 物件上沒有valueOf方法的話就使用toString()方法,若該方法回傳基型值,javascript將之轉換並回傳。
  • 若以上都達不到條件,就會拋出錯誤(TypeError)。
    需要證明是先套用valueOf()方法的話,加上toString試試看
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(注意!是this而不是物件自己本身)。

  • toString() => [object object]
  • valueOf() => this
    所以可以想想看下面的結果為何:
console.log(1 + {});   //?
console.log(1 - {});   //?
  • 物件型別做加減乘除時,都會先套用valueOf方法,也就是object-to-number

當需要將物件轉成字串時,先試試toString() object-to-string

  • 如果該物件有toString()方法,javascript會呼叫他,如果回傳的是一個基型值(primitive),javascript會把那個值轉換成字串(primitive-to-string,也就是會用到wrapper)(不是字串的話),並回傳結果。
  • 若沒有toString()方法,或是回傳的不是基型值時,就會改呼叫valueOf()方法(該方法存在的話),若回傳的是基型值,就會把基型值轉換成字串,並回傳轉換成字串後的值。
  • 若以上皆非,就會拋出TypeError錯誤

尚未有邦友留言

立即登入留言