iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 25
0
Day 25

我不想理你是歐洲人、美洲人、非洲人或哪國人,我就是要說中文。

常常聽到人家說 JavaScript 是弱型別語言,剛開始學程式的時候真的有點一頭霧水,進一步的了解,才知道在程式語言的分類上,有所謂強型別(Strong type)和弱型別(Weak type)語言之分,強弱是相對的,但強弱之間並沒有絕對,而是依語言對型態檢查的嚴格程度,以及型態轉換的規則是否多元而定論。

JavaScript 是偏向弱型別語言的,我們會發現 JavaScript 雖然有型別之分,但是常一不小心就可能踩到雷,或者是被自動轉型,這也算是 JavaScript 難掌控的原因之一吧?例如,我們可以拿字串來做運算,這很怪,但是對 JavaScript 卻是可行的。

兩個 String 相減的結果變成 number 的型別。

let result = '42' - '2';
result; // 40
typeof(result); // number 

也因此,JavaScript 有許多內建的轉型別方法,方便我們轉換型別 轉斜為正?

Array.prototype.toString() - JavaScript | MDN

原型: Array.prototype.toString()
功能: 將指定的陣列和元素轉成字串。
改變: 不會改變原陣列。
語法: arr.toString()
回傳值: 一個表示指定的數組及其元素的字符串。
參數:

toString() 轉型別為字串

toString()顧名思義,可透過它將指定的陣列和元素轉成字串,然後在把這這陣列「打包」成一個字符串回傳回來。
原理是將每個陣列裡的元素轉成字串(必要時會呼叫元素的toString()方法),然後連同字串用逗號分隔後的輸出,輸出時並不會包含中括號或任何在陣列裡的元素界定符號也就是說,如果陣列裡面還有陣列,陣列的 [ ] 會一併消除。

[1,2,3].toString(); // "1,2,3"
["a","b","c"].toString(); // "a,b,c"
[1,[2,'c']].toString(); // "1,2,c"

toString()在遇到其他型別的元素時會如何轉型?我們可以觀察到,很有趣的null, undefined,NaN和空元素都被消失了(但逗號還留著);陣列被去中括號,而物件型別反而轉成了 ˋ[object Object]`。到底轉型的規則是什麼,還真的需要好好探究一下。

[null, {a:42}, 82, , true, undefined, ["hi","hello"], NaN].toString();
// ",[object Object],82,,true,,hi,hello,NaN"

你們是孿生兄弟嗎?

toString()也常常被拿來和join()做比較,兩這到底有什麼差別呢?我們可以以同樣有各種型別的元素陣列,讓兩個方法出裡看看結果:

// 使用 toString() 轉字串
[null, {a:42}, 82, , true, undefined, ["hi","hello"], NaN].toString();
// ",[object Object],82,,true,,hi,hello,NaN"

// 使用 join() 轉字串
[null, {a:42}, 82, , true, undefined, ["hi","hello"], NaN].join();
// ",[object Object],82,,true,,hi,hello,NaN"

結果是一模一樣!這下真的昏頭了,看來,真需要請教前輩這兩個方法的地層運作,但如果說要有什麼不同,是join()可以選擇元素間的分隔符號,但toString() 卻不行。或許,如果單純想把陣列轉成字串,那麼使用toString()會比較純粹些。大家怎麼看呢?

後續: 感謝胡大提醒,原來 spec 有寫 (請看留言),也就是說,使用toString()的結果與使用內建join()方法時不帶參數的結果是相同的。

放假日,今天到這就好~

如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~


上一篇
JS 把陣列 Array 所有元素併成字串,且可任意穿插符號的 join()
下一篇
JS 把陣列 Array 轉成字串與本地化的 toLocaleString()
系列文
JavaScript之一定要了解的 Array 與方法32

2 則留言

0
huli
iT邦新手 5 級 ‧ 2019-10-10 15:32:30

好奇幫你翻了一下 ES3 的 spec(賄選 ES3 是因為比 ES6 篇幅少很多,但除了 ES6 新的特性之外其他 spec 應該都差不多)

The result of calling this function is the same as if the built-in join method were invoked for this object with no argument.

https://ithelp.ithome.com.tw/upload/images/20191010/20091346vk8dthLou1.png

tsuifei iT邦新手 5 級‧ 2019-10-11 11:01:46 檢舉

看spec 果然比較精準,老實說,我看spec還很弱,正慢慢適應中。

昨天夜半看了一下其他人寫的 toStraing() 有閃到寫到toStraing() 等同 join()不帶參數。原來spec就有寫。

感謝胡大提示,真的要以spec回主才是王道!

0
ayugioh2003
iT邦新手 5 級 ‧ 2019-10-10 23:35:38

let result = '42' - '2';
result; // 1
typeof(result); // number

這邊的 result 的註解本來是要打成 40 嗎 ~

tsuifei iT邦新手 5 級‧ 2019-10-11 10:51:32 檢舉

ayugioh2003 謝謝你~修改過來了。
應該是筆誤,想寫的是‘42' - '2'
有時中英文切換沒看到就誤打了

感謝感謝~

我要留言

立即登入留言