【js 基礎系列】'ss'、String('ss')、new String('ss') 的區別

js 中我們創建字符串的方式有三種,如下。其中str、str1爲基本字符串,str2爲字符串對象,Boolean、Number 類似。

var str = 'test'
var str1 = String('test')
var str2 = new String('test')

我們使用 typeof 判斷其類型,可以得到如下結果。

typeof str // string
typeof str1 // string
typeof str2 // object

當我們對他們進行比較時,會發現使用全等符去判斷基本字符串和字符串對象會返回 false。

var str = 'test'
var str1 = String('test')
var str2 = new String('test')

str === str1 // true
str === str2 // false

// 雙等時相等
str == str1 // true
str == str2 // true

那麼爲什麼他們不相等呢??

js 的內存空間分爲三種,棧(stack)堆(heap)(一般也會歸類爲棧中)。棧是一種先進後出的列表結構,如一個水杯中放入雞蛋,我們需要先取出後放入的雞蛋才能去取先放入的雞蛋。堆是一種經過排序的樹形數據結構。

其中棧存放變量堆存放複雜對象池存放常量,所以也叫常量池。

上面的三種字符串,會有不同的存儲過程。

  • 基本字符串會先在中創建變量 str,然後在常量池中尋找內容爲 test 的對象,如果找到就將 str 指向 test,如果沒有找到就在常量池中創建 test 然後 str 指向 test。當我們執行 str = ‘test2’ 重新賦值時,會重新執行上面的過程,尋找 test2,如果找到就將 str 指向 test2 否則重新創建然後指向,這也是爲什麼會說字符串是不可以改變的。
  • 字符串對象則會在中創建一個字符串對象,然後將棧中創建的變量指向對應的對象,當我們新創建一個同樣的字符串 var str3 = new String(‘test’) 時,會重新創建,所以 str3 === str2 會返回 false
var str = 'test'
var str1 = String('test')
var str2 = new String('test')
var str3 = new String('test')

str3 === str2 // false
str3 == str2 // false

str3 == str1 // true

'1' == new String('1') // true
new String('1') == new String('1') // false

可能有人會疑問,上面的代碼中,str3 == str1 會返回 true 爲什麼 str3 == str2 會返回 false呢?

我們解析一下他的過程

  1. 當 str3 == str1 執行時,這裏是基本類型和引用類型的比較,此時雙等號下會執行隱式類型轉換。
  2. 引用類型轉換爲基本類型會使用 ToPrimitive(input, PreferredType?) 抽象規則,這裏會先調用 valueOf 方法。
  3. 此時 str2 會轉換爲基本字符串,此時比較結果相等。
  4. 而 str2 == str3 ,是引用類型和引用類型的比較,會比較其對象的地址,所以會返回 false。

注: 實際上,js 有三種特殊的引用類型:String、Number、Boolean 。被稱爲 基本包裝類型 他們和普通的引用類型有一些差異,詳情
那爲什麼我們在使用基本字符串時也可以使用字符串對象的方法呢?

MDN - String 一節 中有相關的描述。

請注意區分 JavaScript 字符串對象和基本字符串值 . ( 對於 Boolean 和Numbers 也同樣如此.)
字符串字面量 (通過單引號或雙引號定義) 和 直接調用 String 方法(沒有通過 new 生成字符串對象實例)的字符串都是基本字符串。JavaScript會自動將基本字符串轉換爲字符串對象,只有將基本字符串轉化爲字符串對象之後纔可以使用字符串對象的方法。當基本字符串需要調用一個字符串對象纔有的方法或者查詢值的時候(基本字符串是沒有這些方法的),JavaScript 會自動將基本字符串轉化爲字符串對象並且調用相應的方法或者執行查詢

所以我們的基本字符串可以調用字符串對象的方法。

這裏特別說明一下 Boolean 的基本包裝類型。邏輯判斷中,new Boolean(false) 會被當做 true 去處理,所以判斷時最好使用 valueOf 去返回基本類型的值。示例如下

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章