- JavaScript重難點實例精講
- 周雄
- 1610字
- 2020-10-30 15:51:53
1.3.1 String類型的定義與調用
在JavaScript中,有3種定義字符串的方式,分別是字符串字面量,直接調用String()函數(shù)與new String()構造函數(shù)。
1. 字符串字面量
字符串字面量就是直接通過單引號或者雙引號定義字符串的方式。
需要注意的是,在JavaScript中,單引號和雙引號是等價的,都可以用來定義字符串,只不過使用單引號開頭的字符串就要使用單引號結尾,使用雙引號開頭的字符串就要使用雙引號結尾。
var str = 'hello JavaScript'; // 正確寫法 var str2 = "hello html"; // 正確寫法 var str = 'hello css"; // 錯誤寫法,首尾符號不一樣
2. 直接調用String()函數(shù)
直接調用String()函數(shù),會將傳入的任何類型的值轉換成字符串類型,在轉換時遵循的規(guī)則如下。
① 如果是Number類型的值,則直接轉換成對應的字符串。
String(123); // '123' String(123.12); // '123.12'
② 如果是Boolean類型的值,則直接轉換成'true'或者'false'。
String(true); // 'true' String(false); // 'false'
③ 如果值為null,則返回字符串'null';
String(null); // 'null'
④ 如果值為undefined,則返回字符串'undefined';
String(unde?ned); // 'unde?ned'
⑤ 如果值為字符串,則直接返回字符串本身;
String('this is a string'); // 'this is a string'
⑥ 如果值為引用類型,則會先調用toString()函數(shù)獲取返回值,將返回值按照上述步驟①~⑤判斷能否轉換字符串類型,如果都不滿足,則會調用對象的valueOf()函數(shù)獲取返回值,并將返回值重新按照步驟①~⑤判斷能否轉換成字符串類型,如果也不滿足,則會拋出類型轉換的異常。
以下是通過toString()函數(shù)將對象正確轉換成String類型的示例。
var obj = { age: 21, valueOf: function () { return this.age; }, toString: function () { return 'good'; } }; String(obj); // 'good'
以下是通過valueOf()函數(shù)將對象正確轉換成String類型的示例。
var obj = { age: '21', valueOf: function () { return this.age; }, toString: function () { return []; } }; String(obj); // '21'
如果toString()函數(shù)和valueOf()函數(shù)返回的都是對象類型而無法轉換成原生類型時,則會拋出類型轉換的異常。
var obj = { age: '21', valueOf: function () { return []; }, toString: function () { return []; } }; String(obj); // 拋出異常TypeError: Cannot convert object to primitive value
3. new String()構造函數(shù)
new String()構造函數(shù)使用new運算符生成String類型的實例,對于傳入的參數(shù)同樣采用和上述String()函數(shù)一樣的類型轉換策略,最后的返回值是一個String類型對象的實例。
new String('hello JavaScript'); // String {"hello JavaScript"}
4. 三者在作比較時的區(qū)別
使用第一種字符串字面量方式和第二種直接調用String()函數(shù)的方式得到的字符串都是基本字符串,而通過第三種方式,new運算符生成的字符串是字符串對象。
基本字符串在作比較時,只需要比較字符串的值即可;而在比較字符串對象時,比較的是對象所在的地址。
我們看看以下用來測試相等的實例。
var str = 'hello'; var str2 = String(str); var str3 = String('hello'); var str4 = new String(str); var str5 = new String(str); var str6 = new String('hello'); str === str2; // true str2 === str3; // true str3 === str4; // false str4 === str5; // false str5 === str6; // false
首先對于str、str2和str3,因為都是基本字符串,只需要比較字符串的值即可,三者字符串值都為'hello',所以三者是互相嚴格相等的。
str === str2; // true str2 === str3; // true
其次,對于str4、str5和str6,因為是使用new運算符生成的String類型的實例,所以在比較時需要判斷變量是否指向同一個對象,即內存地址是否相同,很明顯str4、str5、str6都是在內存中新生成的地址,彼此各不相同。
str4 !== str5; // true str5 !== str6; // true str4 !== str6; // true
同樣,對于基本字符串和字符串對象的比較,在判斷嚴格相等時,也會返回“false”。
str === str4; // false str2 === str4; // false
5. 函數(shù)的調用
在String對象的原型鏈上有一系列的函數(shù),例如indexOf()函數(shù)、substring()函數(shù)、slice()函數(shù)等,通過String對象的實例可以調用這些函數(shù)做字符串的處理。
但是我們發(fā)現(xiàn),采用字面量方式定義的字符串沒有通過new運算符生成String對象的實例也能夠直接調用原型鏈上的函數(shù)。
'hello'.indexOf('e'); // 1 'hello'.substring(1); // 'ello' 'hello'.slice(1); // 'ello'
這是為什么呢?
實際上基本字符串本身是沒有字符串對象的函數(shù),而在基本字符串調用字符串對象才有的函數(shù)時,JavaScript會自動將基本字符串轉換為字符串對象,形成一種包裝類型,這樣基本字符串就可以正常調用字符串對象的方法了。
基本字符串和字符串對象在經過eval()函數(shù)處理時,會產生不同的結果。
eval()函數(shù)會將基本字符串作為源代碼處理,如果涉及表達式會直接進行運算,返回運算后的結果;而字符串對象則會被看作對象處理,返回對象本身。
var s1 = '2 + 2'; // 創(chuàng)建一個字符串字面量 var s2 = new String('2 + 2'); // 創(chuàng)建一個對象字符串 console.log(eval(s1)); // 4 console.log(eval(s2)); // String {"2 + 2"}
通過實例可以看出,在使用eval()函數(shù)處理字符串字面量時,進行了2 + 2 = 4的算術運算,并返回“4”;而使用eval()函數(shù)處理對象字符串時,會將'2 + 2'看成是一個對象,而不會進行運算,直接輸出字符串本身。