官术网_书友最值得收藏!

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'看成是一個對象,而不會進行運算,直接輸出字符串本身。

主站蜘蛛池模板: 高雄县| 宜都市| 来凤县| 开远市| 永靖县| 禄丰县| 华亭县| 襄汾县| 香港| 河源市| 四川省| 大姚县| 安宁市| 大竹县| 镇巴县| 晴隆县| 岑巩县| 蓝田县| 卢湾区| 邯郸市| 博湖县| 松潘县| 通山县| 澄迈县| 丰县| 兴和县| 凤山市| 开封县| 尚志市| 灵台县| 大余县| 崇州市| 城市| 华蓥市| 金寨县| 温泉县| 姜堰市| 久治县| 贺兰县| 贺州市| 工布江达县|