V8實現(xiàn)字符串拼接
前言
在之前的一篇文章 JavaScript 隱式類型轉(zhuǎn)換規(guī)則中有提到,JavaScript 中的加號可以用來拼接字符串。本文就具體來介紹一下 V8 是如何來執(zhí)行這一操作的......
V8 是怎么執(zhí)行加法操作的?
當(dāng)有兩個值相加的時候,比如:
a+b
通俗理解,V8 會提供了一個 ToPrimitive
方法,其作用是將 a
和 b
轉(zhuǎn)換為原始數(shù)據(jù)類型,其轉(zhuǎn)換流程如下:
- 先檢測該對象中是否存在
valueOf
方法,如果有并返回了原始類型,那么就使用該值進(jìn)行強(qiáng)制類型轉(zhuǎn)換。 - 如果
valueOf
沒有返回原始類型,那么就使用toString
方法的返回值。 - 如果
vauleOf
和toString
兩個方法都不返回基本類型值,便會觸發(fā)一個TypeError
的錯誤。
將對象轉(zhuǎn)換為原始類型的流程圖如下所示:
當(dāng) V8 執(zhí)行 1+"2" 時,因為這是兩個原始值相加,原始值相加的時候,如果其中一項是字符串,那么 V8 會默認(rèn)將另外一個值也轉(zhuǎn)換為字符串,相當(dāng)于執(zhí)行了下面的操作:
Number(1).toString() + "2"
這里,把數(shù)字 1
偷偷轉(zhuǎn)換為字符串 "1"
的過程也稱為強(qiáng)制類型轉(zhuǎn)換,因為這種轉(zhuǎn)換是隱式的,所以如果我們不熟悉語義,那么就很容易判斷錯誤。
我們還可以再看一個例子來驗證上面流程,你可以看下面的代碼:
var Obj = { toString() { return '200' }, valueOf() { return 100 } } Obj+3
執(zhí)行這段代碼,你覺得應(yīng)該返回什么內(nèi)容呢?由于需要先使用 ToPrimitive
方法將 Obj
轉(zhuǎn)換為原始類型,而 ToPrimitive
會優(yōu)先調(diào)用對象中的 valueOf
方法,由于 valueOf
返回了 100
,那么 Obj
就會被轉(zhuǎn)換為數(shù)字 100
,那么數(shù)字 100
加數(shù)字 3
,那么結(jié)果當(dāng)然是 103
了。
如果改造一下代碼,讓 valueOf
方法和 toString
方法都返回對象,其改造后的代碼如下:
var Obj = { toString() { return new Object() }, valueOf() { return new Object() } } Obj+3
再執(zhí)行這段代碼,你覺得應(yīng)該返回什么內(nèi)容呢?因為 ToPrimitive
會先調(diào)用 valueOf
方法,發(fā)現(xiàn)返回的是一個對象,并不是原生類型,當(dāng) ToPrimitive
繼續(xù)調(diào)用 toString
方法時,發(fā)現(xiàn) toString
返回的也是一個對象,都是對象,就無法執(zhí)行相加運(yùn)算了,這時就會拋出一個異常,異常如下所示:
Uncaught TypeError: Cannot convert object to primitive value
提示的是類型錯誤,錯誤原因是無法將對象類型轉(zhuǎn)換為原始類型。所以說,在執(zhí)行加法操作的時候,V8 會通過 ToPrimitive
方法將對象類型轉(zhuǎn)換為原始類型,最后就是兩個原始類型相加,如果其中一個值的類型是字符串時,則另一個值也需要強(qiáng)制轉(zhuǎn)換為字符串,然后做字符串的連接運(yùn)算。在其他情況時,所有的值都會轉(zhuǎn)換為數(shù)字類型值,然后做數(shù)字的相加。
總結(jié)
在 JavaScript 中,類型系統(tǒng)是依據(jù) ECMAScript 標(biāo)準(zhǔn)來實現(xiàn)的,所以 V8 會嚴(yán)格根據(jù) ECMAScript 標(biāo)準(zhǔn)來執(zhí)行。在執(zhí)行加法過程中,V8 會先通過 ToPrimitive
函數(shù),將對象轉(zhuǎn)換為原始字符串或者是數(shù)字類型,在轉(zhuǎn)換過程中,ToPrimitive
會先調(diào)用對象的 valueOf
方法,如果沒有 valueOf
方法,則調(diào)用 toString
方法,如果 vauleOf
和 toString
兩個方法都不返回基本類型值,便會觸發(fā)一個 TypeError
的錯誤。
到此這篇關(guān)于V8實現(xiàn)字符串拼接的文章就介紹到這了,更多相關(guān)V8 字符串拼接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實現(xiàn)電商平臺商品細(xì)節(jié)圖
這篇文章主要為大家詳細(xì)介紹了JavaScript實現(xiàn)電商平臺商品細(xì)節(jié)圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06JavaScript動態(tài)添加css樣式和script標(biāo)簽
這篇文章主要介紹了JavaScript動態(tài)添加css樣式和script標(biāo)簽的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-07-07js將字符串轉(zhuǎn)成正則表達(dá)式的實現(xiàn)方法
js將字符串轉(zhuǎn)成正則表達(dá)式的實現(xiàn)方法。其實很簡單哦!需要的朋友可以過來參考下,希望對大家有所幫助2013-11-11JS通過調(diào)用微信API實現(xiàn)微信支付功能的方法示例
這篇文章主要介紹了JS通過調(diào)用微信API實現(xiàn)微信支付功能的方法,結(jié)合具體實例形式分析了javascript微信支付接口的調(diào)用方法與相關(guān)注意事項,需要的朋友可以參考下2017-06-06js實現(xiàn)七夕表白彈幕效果 jQuery實現(xiàn)彈幕技術(shù)
這篇文章主要介紹了js實現(xiàn)七夕表白彈幕效果,jQuery實現(xiàn)彈幕技術(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08JavaScript打印網(wǎng)頁指定區(qū)域的例子
這篇文章主要介紹了JavaScript打印網(wǎng)頁指定區(qū)域的例子,需要的朋友可以參考下2014-05-05