《JavaScript 闖關(guān)記》之基本包裝類型
為了便于操作基本類型值,JavaScript 還提供了3個(gè)特殊的引用類型:Boolean、Number 和 String。實(shí)際上,每當(dāng)讀取一個(gè)基本類型值的時(shí)候,后臺(tái)就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的基本包裝類型的對(duì)象,從而讓我們能夠調(diào)用一些方法來操作這些數(shù)據(jù)。來看下面的例子。
- var s1 = "some text";
- var s2 = s1.substring(2);
這個(gè)例子中的變量 s1 包含一個(gè)字符串,字符串當(dāng)然是基本類型值。而下一行調(diào)用了 s1 的 substring() 方法,并將返回的結(jié)果保存在了 s2 中。我們知道,基本類型值不是對(duì)象,因而從邏輯上講它們不應(yīng)該有方法(盡管如我們所愿,它們確實(shí)有方法)。其實(shí),為了讓我們實(shí)現(xiàn)這種直觀的操作,后臺(tái)已經(jīng)自動(dòng)完成了一系列的處理。當(dāng)?shù)诙写a訪問 s1 時(shí),訪問過程處于一種讀取模式,也就是要從內(nèi)存中讀取這個(gè)字符串的值。而在讀取模式中訪問字符串時(shí),后臺(tái)都會(huì)自動(dòng)完成下列處理。
- 創(chuàng)建 String 類型的一個(gè)實(shí)例;
- 在實(shí)例上調(diào)用指定的方法;
- 銷毀這個(gè)實(shí)例。
可以將以上三個(gè)步驟想象成是執(zhí)行了下列 JavaScript 代碼。
- var s1 = new String("some text");
- var s2 = s1.substring(2);
- s1 = null;
經(jīng)過此番處理,基本的字符串值就變得跟對(duì)象一樣了。而且,上面這三個(gè)步驟也分別適用于 Boolean 和 Number 類型對(duì)應(yīng)的布爾值和數(shù)字值。
引用類型與基本包裝類型的主要區(qū)別就是對(duì)象的生存期。使用 new 操作符創(chuàng)建的引用類型的實(shí)例,在執(zhí)行流離開當(dāng)前作用域之前都一直保存在內(nèi)存中。而自動(dòng)創(chuàng)建的基本包裝類型的對(duì)象,則只存在于一行代碼的執(zhí)行瞬間,然后立即被銷毀。這意味著我們不能在運(yùn)行時(shí)為基本類型值添加屬性和方法。來看下面的例子:
- var s1 = "some text";
- s1.color = "red";
- console.log(s1.color); // undefined
當(dāng)然,可以顯式地調(diào)用 Boolean、Number 和 String 來創(chuàng)建基本包裝類型的對(duì)象。不過,應(yīng)該在絕對(duì)必要的情況下再這樣做,因?yàn)檫@種做法很容易讓人分不清自己是在處理「基本類型」還是「引用類型」的值。對(duì)基本包裝類型的實(shí)例調(diào)用 typeof 會(huì)返回"object",而且所有基本包裝類型的對(duì)象都會(huì)被轉(zhuǎn)換為布爾值 true。
Object 構(gòu)造函數(shù)也會(huì)像工廠方法一樣,根據(jù)傳入值的類型返回相應(yīng)基本包裝類型的實(shí)例。例如:
- var obj = new Object("some text");
- console.log(obj instanceof String); // true
把字符串傳給 Object 構(gòu)造函數(shù),就會(huì)創(chuàng)建 String 的實(shí)例;而傳入數(shù)值參數(shù)會(huì)得到 Number 的實(shí)例,傳入布爾值參數(shù)就會(huì)得到Boolean 的實(shí)例。
要注意的是,使用 new 調(diào)用基本包裝類型的構(gòu)造函數(shù),與直接調(diào)用同名的轉(zhuǎn)型函數(shù)是不一樣的。 例如:
- var value = "25";
- var number = Number(value); // 轉(zhuǎn)型函數(shù)
- console.log(typeof number); // "number"
- var obj = new Number(value); // 構(gòu)造函數(shù)
- console.log(typeof obj); // "object"
盡管我們不建議顯式地創(chuàng)建基本包裝類型的對(duì)象,但它們操作基本類型值的能力還是相當(dāng)重要的。而每個(gè)基本包裝類型都提供了操作相應(yīng)值的便捷方法。
Boolean 類型
Boolean 類型是與布爾值對(duì)應(yīng)的引用類型。要?jiǎng)?chuàng)建 Boolean 對(duì)象,可以像下面這樣調(diào)用 Boolean 構(gòu)造函數(shù)并傳入 true 或 false值。
- var booleanObject = new Boolean(true);
Boolean 類型的實(shí)例重寫了 valueOf() 方法,返回基本類型值 true 或 false;重寫了 toString() 方法,返回字符串 "true" 和"false"??墒?,Boolean 對(duì)象在 JavaScript 中的用處不大,因?yàn)樗?jīng)常會(huì)造成人們的誤解。其中最常見的問題就是在布爾表達(dá)式中使用 Boolean 對(duì)象,例如:
- var falseObject = new Boolean(false);
- var result = falseObject && true;
- console.log(result); // true
- var falseValue = false;
- result = falseValue && true;
- console.log(result); // false
在這個(gè)例子中,我們使用 false 值創(chuàng)建了一個(gè) Boolean 對(duì)象。然后,將這個(gè)對(duì)象與基本類型值 true 構(gòu)成了邏輯與表達(dá)式。在布爾運(yùn)算中,false && true 等于 false。可是,示例中的這行代碼是對(duì) falseObject 而不是對(duì)它的值 false 進(jìn)行求值。布爾表達(dá)式中的所有對(duì)象都會(huì)被轉(zhuǎn)換為 true,因此 falseObject 對(duì)象在布爾表達(dá)式中代表的是 true。結(jié)果,true && true 當(dāng)然就等于true 了。
基本類型與引用類型的布爾值還有兩個(gè)區(qū)別。首先,typeof 操作符對(duì)基本類型返回 "boolean",而對(duì)引用類型返回 "object"。其次,由于 Boolean 對(duì)象是 Boolean 類型的實(shí)例,所以使用 instanceof 操作符測(cè)試 Boolean 對(duì)象會(huì)返回 true,而測(cè)試基本類型的布爾值則返回 false。例如:
- console.log(typeof falseObject); // object
- console.log(typeof falseValue); // boolean
- console.log(falseObject instanceof Boolean); // true
- console.log(falseValue instanceof Boolean); // false
理解基本類型的布爾值與 Boolean 對(duì)象之間的區(qū)別非常重要,我們的建議是永遠(yuǎn)不要使用 Boolean 對(duì)象。
Number 類型
Number 是與數(shù)字值對(duì)應(yīng)的引用類型。要?jiǎng)?chuàng)建 Number 對(duì)象,可以在調(diào)用 Number 構(gòu)造函數(shù)時(shí)向其中傳遞相應(yīng)的數(shù)值。下面是一個(gè)例子。
- var numberObject = new Number(10);
與 Boolean 類型一樣,Number 類型也重寫了 valueOf()、toLocaleString() 和 toString() 方法。重寫后的 valueOf() 方法返回對(duì)象表示的基本類型的數(shù)值,另外兩個(gè)方法則返回字符串形式的數(shù)值。可以為 toString() 方法傳遞一個(gè)表示基數(shù)的參數(shù),告訴它返回幾進(jìn)制數(shù)值的字符串形式,如下面的例子所示。
- var num = 10;
- console.log(num.toString()); // "10"
- console.log(num.toString(2)); // "1010"
- console.log(num.toString(8)); // "12"
- console.log(num.toString(10)); // "10"
- console.log(num.toString(16)); // "a"
除了繼承的方法之外,Number 類型還提供了一些用于將數(shù)值格式化為字符串的方法。其中,toFixed() 方法會(huì)按照指定的小數(shù)位返回?cái)?shù)值的字符串表示,例如:
- var num = 10;
- console.log(num.toFixed(2)); // "10.00"
這里給 toFixed() 方法傳入了數(shù)值 2,意思是顯示幾位小數(shù)。于是,這個(gè)方法返回了 "10.00",即以 0 填補(bǔ)了必要的小數(shù)位。如果數(shù)值本身包含的小數(shù)位比指定的還多,那么接近指定的***小數(shù)位的值就會(huì)舍入,如下面的例子所示。
- var num = 10.005;
- console.log(num.toFixed(2)); // "10.01"
能夠自動(dòng)舍入的特性,使得 toFixed() 方法很適合處理貨幣值。
但需要注意的是,不同瀏覽器給這個(gè)方法設(shè)定的舍入規(guī)則可能會(huì)有所不同。
在給 toFixed() 傳入0的情況下,IE8 及之前版本不能正確舍入范圍在{(-0.94,-0.5],[0.5,0.94)}之間的值。對(duì)于這個(gè)范圍內(nèi)的值,IE8 會(huì)返回0,而不是-1或1;其他瀏覽器都能返回正確的值。IE9 修復(fù)了這個(gè)問題。
toFixed() 方法可以表示帶有0到20個(gè)小數(shù)位的數(shù)值。但這只是標(biāo)準(zhǔn)實(shí)現(xiàn)的范圍,有些瀏覽器也可能支持更多位數(shù)。
另外可用于格式化數(shù)值的方法是 toExponential(),該方法返回以指數(shù)表示法(也稱 e 表示法)表示的數(shù)值的字符串形式。與toFixed() 一樣,toExponential() 也接收一個(gè)參數(shù),而且該參數(shù)同樣也是指定輸出結(jié)果中的小數(shù)位數(shù)??聪旅娴睦印?/p>
- var num = 10;
- console.log(num.toExponential(1)); // "1.0e+1"
以上代碼輸出了 "1.0e+1";不過,這么小的數(shù)值一般不必使用 e 表示法。如果你想得到表示某個(gè)數(shù)值的最合適的格式,就應(yīng)該使用toPrecision() 方法。
對(duì)于一個(gè)數(shù)值來說,toPrecision() 方法可能會(huì)返回固定大小(fixed)格式,也可能返回指數(shù)(exponential)格式;具體規(guī)則是看哪種格式最合適。這個(gè)方法接收一個(gè)參數(shù),即表示數(shù)值的所有數(shù)字的位數(shù)(不包括指數(shù)部分)。請(qǐng)看下面的例子。
- var num = 99;
- console.log(num.toPrecision(1)); // "1e+2"
- console.log(num.toPrecision(2)); // "99"
- console.log(num.toPrecision(3)); // "99.0"
以上代碼首先完成的任務(wù)是以一位數(shù)來表示 99,結(jié)果是 "1e+2",即 100。因?yàn)橐晃粩?shù)無法準(zhǔn)確地表示 99,因此 toPrecision()就將它向上舍入為 100,這樣就可以使用一位數(shù)來表示它了。而接下來的用兩位數(shù)表示 99,當(dāng)然還是 "99"。***,在想以三位數(shù)表示 99 時(shí),toPrecision() 方法返回了 "99.0"。實(shí)際上,toPrecision() 會(huì)根據(jù)要處理的數(shù)值決定到底是調(diào)用 toFixed() 還是調(diào)用 toExponential()。而這三個(gè)方法都可以通過向上或向下舍入,做到以最準(zhǔn)確的形式來表示帶有正確小數(shù)位的值。
toPrecision() 方法可以表現(xiàn)1到21位小數(shù)。但這只是標(biāo)準(zhǔn)實(shí)現(xiàn)的范圍,有些瀏覽器也可能支持更多位數(shù)。
與 Boolean 對(duì)象類似,Number 對(duì)象也以后臺(tái)方式為數(shù)值提供了重要的功能。但與此同時(shí),我們?nèi)匀徊唤ㄗh直接實(shí)例化 Number 類型,而原因與顯式創(chuàng)建 Boolean 對(duì)象一樣。具體來講,就是在使用 typeof 和 instanceof 操作符測(cè)試基本類型數(shù)值與引用類型數(shù)值時(shí),得到的結(jié)果完全不同,如下面的例子所示。
- var numberObject = new Number(10);
- var numberValue = 10;
- console.log(typeof numberObject); // "object"
- console.log(typeof numberValue); // "number"
- console.log(numberObject instanceof Number); // true
- console.log(numberValue instanceof Number); // false
String 類型
String 類型是字符串的對(duì)象包裝類型,可以像下面這樣使用 String 構(gòu)造函數(shù)來創(chuàng)建。
- var stringObject = new String("hello world");
String 對(duì)象的方法也可以在所有基本的字符串值中訪問到。其中,繼承的 valueOf()、toLocaleString() 和 toString() 方法,都返回對(duì)象所表示的基本字符串值。
String 類型的每個(gè)實(shí)例都有一個(gè) length 屬性,表示字符串中包含多個(gè)字符。來看下面的例子。
- var stringValue = "hello world";
- console.log(stringValue.length); // 11
應(yīng)該注意的是,即使字符串中包含雙字節(jié)字符(不是占一個(gè)字節(jié)的 ASCII 字符),每個(gè)字符也仍然算一個(gè)字符。例如:
- var stringValue = "大家好";
- console.log(stringValue.length); // 3
String 類型提供了很多方法,用于輔助完成對(duì) JavaScript 中字符串的解析和操作。
字符方法
兩個(gè)用于訪問字符串中特定字符的方法是:charAt() 和 charCodeAt()。這兩個(gè)方法都接收一個(gè)參數(shù),即基于0的字符位置。其中,charAt() 方法以單字符字符串的形式返回給定位置的那個(gè)字符(JavaScript 中沒有字符類型)。例如:
- var stringValue = "hello world";
- console.log(stringValue.charAt(1)); // "e"
如果你想得到的不是字符而是字符編碼,那么就要像下面這樣使用 charCodeAt() 了。例如:
- var stringValue = "hello world";
- console.log(stringValue.charCodeAt(1)); // 101,101是小寫字母"e"的字符編碼
ECMAScript 5 還定義了另一個(gè)訪問個(gè)別字符的方法。在支持瀏覽器中,可以使用方括號(hào)加數(shù)字索引來訪問字符串中的特定字符,如下面的例子所示。
- var stringValue = "hello world";
- console.log(stringValue[1]); // "e"
字符串操作方法
下面介紹與操作字符串有關(guān)的幾個(gè)方法。***個(gè)就是 concat(),用于將一或多個(gè)字符串拼接起來,返回拼接得到的新字符串。先來看一個(gè)例子。
- var stringValue = "hello ";
- var result = stringValue.concat("world");
- console.log(result); // "hello world"
- console.log(stringValue); // "hello"
實(shí)際上,concat() 方法可以接受任意多個(gè)參數(shù),也就是說可以通過它拼接任意多個(gè)字符串。再看一個(gè)例子:
- var stringValue = "hello ";
- var result = stringValue.concat("world", "!");
- console.log(result); // "hello world!"
- console.log(stringValue); // "hello"
雖然 concat() 是專門用來拼接字符串的方法,但實(shí)踐中使用更多的還是加號(hào)操作符 + 。而且,使用加號(hào)操作符 + 在大多數(shù)情況下都比使用 concat()方法要簡便易行(特別是在拼接多個(gè)字符串的情況下)。
JavaScript 還提供了三個(gè)基于子字符串創(chuàng)建新字符串的方法:slice()、substr() 和 substring()。這三個(gè)方法都會(huì)返回被操作字符串的一個(gè)子字符串,而且也都接受一或兩個(gè)參數(shù)。***個(gè)參數(shù)指定子字符串的開始位置,第二個(gè)參數(shù)(在指定的情況下)表示子字符串到哪里結(jié)束。具體來說,slice() 和 substring() 的第二個(gè)參數(shù)指定的是子字符串***一個(gè)字符后面的位置。而 substr() 的第二個(gè)參數(shù)指定的則是返回的字符個(gè)數(shù)。如果沒有給這些方法傳遞第二個(gè)參數(shù),則將字符串的長度作為結(jié)束位置。與 concat() 方法一樣,slice()、substr() 和 substring()也不會(huì)修改字符串本身的值,它們只是返回一個(gè)基本類型的字符串值,對(duì)原始字符串沒有任何影響。請(qǐng)看下面的例子。
- var stringValue = "hello world";
- console.log(stringValue.slice(3)); // "lo world"
- console.log(stringValue.substring(3)); // "lo world"
- console.log(stringValue.substr(3)); // "lo world"
- console.log(stringValue.slice(3, 7)); // "lo w"
- console.log(stringValue.substring(3,7)); // "lo w"
- console.log(stringValue.substr(3, 7)); // "lo worl"
在傳遞給這些方法的參數(shù)是負(fù)值的情況下,它們的行為就不盡相同了。其中,slice() 方法會(huì)將傳入的負(fù)值與字符串的長度相加,substr() 方法將負(fù)的***個(gè)參數(shù)加上字符串的長度,而將負(fù)的第二個(gè)參數(shù)轉(zhuǎn)換為0。***,substring() 方法會(huì)把所有負(fù)值參數(shù)都轉(zhuǎn)換為0。下面來看例子。
- var stringValue = "hello world";
- console.log(stringValue.slice(-3)); // "rld"
- console.log(stringValue.substring(-3)); // "hello world"
- console.log(stringValue.substr(-3)); // "rld"
- console.log(stringValue.slice(3, -4)); // "lo w"
- console.log(stringValue.substring(3, -4)); // "hel"
- console.log(stringValue.substr(3, -4)); //""(空字符串)
字符串位置方法
有兩個(gè)可以從字符串中查找子字符串的方法:indexOf() 和 lastIndexOf()。這兩個(gè)方法都是從一個(gè)字符串中搜索給定的子字符串,然后返子字符串的位置(如果沒有找到該子字符串,則返回-1)。這兩個(gè)方法的區(qū)別在于:indexOf() 方法從字符串的開頭向后搜索子字符串,而 lastIndexOf() 方法是從字符串的末尾向前搜索子字符串。還是來看一個(gè)例子吧。
- var stringValue = "hello world";
- console.log(stringValue.indexOf("o")); // 4
- console.log(stringValue.lastIndexOf("o")); // 7
這兩個(gè)方法都可以接收可選的第二個(gè)參數(shù),表示從字符串中的哪個(gè)位置開始搜索。換句話說,indexOf()會(huì)從該參數(shù)指定的位置向后搜索,忽略該位置之前的所有字符;而lastIndexOf()則會(huì)從指定的位置向前搜索,忽略該位置之后的所有字符??聪旅娴睦?。
- var stringValue = "hello world";
- console.log(stringValue.indexOf("o", 6)); // 7
- console.log(stringValue.lastIndexOf("o", 6)); // 4
在使用第二個(gè)參數(shù)的情況下,可以通過循環(huán)調(diào)用 indexOf() 或 lastIndexOf() 來找到所有匹配的子字符串,如下面的例子所示:
- var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
- var positions = new Array();
- var pos = stringValue.indexOf("e");
- while(pos > -1){
- positions.push(pos);
- pos = stringValue.indexOf("e", pos + 1);
- }
- console.log(positions); // "3,24,32,35,52"
trim() 方法
ECMAScript 5 為所有字符串定義了 trim() 方法。這個(gè)方法會(huì)創(chuàng)建一個(gè)字符串的副本,刪除前置及后綴的所有空格,然后返回結(jié)果。例如:
- var stringValue = " hello world ";
- var trimmedStringValue = stringValue.trim();
- console.log(stringValue); // " hello world "
- console.log(trimmedStringValue); // "hello world"
字符串大小寫轉(zhuǎn)換方法
JavaScript 中涉及字符串大小寫轉(zhuǎn)換的方法有4個(gè):toLowerCase()、toLocaleLowerCase()、toUpperCase() 和toLocaleUpperCase()。其中,toLowerCase() 和 toUpperCase() 是兩個(gè)經(jīng)典的方法,借鑒自 java.lang.String 中的同名方法。而 toLocaleLowerCase() 和 toLocaleUpperCase() 方法則是針對(duì)特定地區(qū)的實(shí)現(xiàn)。對(duì)有些地區(qū)來說,針對(duì)地區(qū)的方法與其通用方法得到的結(jié)果相同,但少數(shù)語言(如土耳其語)會(huì)為 Unicode 大小寫轉(zhuǎn)換應(yīng)用特殊的規(guī)則,這時(shí)候就必須使用針對(duì)地區(qū)的方法來保證實(shí)現(xiàn)正確的轉(zhuǎn)換。以下是幾個(gè)例子。
- var stringValue = "hello world";
- console.log(stringValue.toLocaleUpperCase()); // "HELLO WORLD"
- console.log(stringValue.toUpperCase()); // "HELLO WORLD"
- console.log(stringValue.toLocaleLowerCase()); // "hello world"
- console.log(stringValue.toLowerCase()); // "hello world"
一般來說,在不知道自己的代碼將在哪種語言環(huán)境中運(yùn)行的情況下,還是使用針對(duì)地區(qū)的方法更穩(wěn)妥一些。
字符串的模式匹配方法
String 類型定義了幾個(gè)用于在字符串中匹配模式的方法。***個(gè)方法就是 match(),在字符串上調(diào)用這個(gè)方法,本質(zhì)上與調(diào)用RegExp 的 exec() 方法相同。match() 方法只接受一個(gè)參數(shù),要么是一個(gè)正則表達(dá)式,要么是一個(gè) RegExp 對(duì)象。來看下面的例子。
- var text = "cat, bat, sat, fat";
- var pattern = /.at/;
- // 與pattern.exec(text)相同
- var matches = text.match(pattern);
- console.log(matches.index); // 0
- console.log(matches[0]); // "cat"
- console.log(pattern.lastIndex); // 0
另一個(gè)用于查找模式的方法是 search()。這個(gè)方法的唯一參數(shù)與 match() 方法的參數(shù)相同:由字符串或 RegExp 對(duì)象指定的一個(gè)正則表達(dá)式。search() 方法返回字符串中***個(gè)匹配項(xiàng)的索引;如果沒有找到匹配項(xiàng),則返回-1。而且,search() 方法始終是從字符串開頭向后查找模式??聪旅娴睦?。
- var text = "cat, bat, sat, fat";
- var pos = text.search(/at/);
- console.log(pos); // 1,即"at"***次出現(xiàn)的位置
為了簡化替換子字符串的操作,JavaScript 提供了 replace() 方法。這個(gè)方法接受兩個(gè)參數(shù):***個(gè)參數(shù)可以是一個(gè) RegExp 對(duì)象或者一個(gè)字符串(這個(gè)字符串不會(huì)被轉(zhuǎn)換成正則表達(dá)式),第二個(gè)參數(shù)可以是一個(gè)字符串或者一個(gè)函數(shù)。如果***個(gè)參數(shù)是字符串,那么只會(huì)替換***個(gè)子字符串。要想替換所有子字符串,唯一的辦法就是提供一個(gè)正則表達(dá)式,而且要指定全局 g 標(biāo)志,如下所示。
- var text = "cat, bat, sat, fat";
- var result = text.replace("at", "ond");
- console.log(result); // "cond, bat, sat, fat"
- result = text.replace(/at/g, "ond");
- console.log(result); // "cond, bond, sond, fond"
***一個(gè)與模式匹配有關(guān)的方法是 split(),這個(gè)方法可以基于指定的分隔符將一個(gè)字符串分割成多個(gè)子字符串,并將結(jié)果放在一個(gè)數(shù)組中。分隔符可以是字符串,也可以是一個(gè) RegExp 對(duì)象(這個(gè)方法不會(huì)將字符串看成正則表達(dá)式)。split() 方法可以接受可選的第二個(gè)參數(shù),用于指定數(shù)組的大小,以便確保返回的數(shù)組不會(huì)超過既定大小。請(qǐng)看下面的例子。
- var colorText = "red,blue,green,yellow";
- var colors1 = colorText.split(","); // ["red", "blue", "green", "yellow"]
- var colors2 = colorText.split(",", 2); // ["red", "blue"]
- localeCompare() 方法
這個(gè)方法比較兩個(gè)字符串,并返回下列值中的一個(gè):
如果字符串在字母表中應(yīng)該排在字符串參數(shù)之前,則返回一個(gè)負(fù)數(shù)(大多數(shù)情況下是-1,具體的值要視實(shí)現(xiàn)而定);
如果字符串等于字符串參數(shù),則返回0;
如果字符串在字母表中應(yīng)該排在字符串參數(shù)之后,則返回一個(gè)正數(shù)(大多數(shù)情況下是1,具體的值同樣要視實(shí)現(xiàn)而定)。
下面是幾個(gè)例子。
- var stringValue = "yellow";
- console.log(stringValue.localeCompare("brick")); // 1
- console.log(stringValue.localeCompare("yellow")); // 0
- console.log(stringValue.localeCompare("zoo")); // -1
這個(gè)例子比較了字符串 "yellow" 和另外幾個(gè)值:"brick"、"yellow" 和 "zoo"。因?yàn)?"brick" 在字母表中排在 "yellow" 之前,所以 localeCompare() 返回了1;而 "yellow" 等于 "yellow",所以 localeCompare() 返回了0;***,"zoo" 在字母表中排在 "yellow" 后面,所以 localeCompare() 返回了-1。再強(qiáng)調(diào)一次,因?yàn)? localeCompare() 返回的數(shù)值取決于實(shí)現(xiàn),所以***是像下面例子所示的這樣使用這個(gè)方法。
- function determineOrder(value) {
- var result = stringValue.localeCompare(value);
- if (result < 0){
- console.log("The string 'yellow' comes before the string '" + value + "'.");
- } else if (result > 0) {
- console.log("The string 'yellow' comes after the string '" + value + "'.");
- } else {
- console.log("The string 'yellow' is equal to the string '" + value + "'.");
- }
- }
- determineOrder("brick");
- determineOrder("yellow");
- determineOrder("zoo");
使用這種結(jié)構(gòu),就可以確保自己的代碼在任何實(shí)現(xiàn)中都可以正確地運(yùn)行了。
localeCompare() 方法比較與眾不同的地方,就是實(shí)現(xiàn)所支持的地區(qū)(國家和語言)決定了這個(gè)方法的行為。比如,美國以英語作為 JavaScript 實(shí)現(xiàn)的標(biāo)準(zhǔn)語言,因此 localeCompare() 就是區(qū)分大小寫的,于是大寫字母在字母表中排在小寫字母前頭就成為了一項(xiàng)決定性的比較規(guī)則。不過,在其他地區(qū)恐怕就不是這種情況了。
fromCharCode() 方法
另外,String 構(gòu)造函數(shù)本身還有一個(gè)靜態(tài)方法:fromCharCode()。這個(gè)方法的任務(wù)是接收一或多個(gè)字符編碼,然后將它們轉(zhuǎn)換成一個(gè)字符串。從本質(zhì)上來看,這個(gè)方法與實(shí)例方法 charCodeAt() 執(zhí)行的是相反的操作。來看一個(gè)例子:
- console.log(String.fromCharCode(104, 101, 108, 108, 111)); // "hello"
- var s = 'hello';
- for(let i=0;i<s.length;i++){
- console.log(`${s[i]}----${s[i].charCodeAt()}`);
- }
- /*
- "h----104"
- "e----101"
- "l----108"
- "l----108"
- "o----111"
- */
在這里,我們給 fromCharCode() 傳遞的是字符串 "hello" 中每個(gè)字母的字符編碼。
關(guān)卡
- // 挑戰(zhàn)一
- var falseObject = new Object(false);
- console.log(typeof falseObject); // ???
- console.log(falseObject instanceof Object); // ???
- console.log(falseObject instanceof Boolean); // ???
- // 挑戰(zhàn)二
- var numberObject = new Object(100);
- console.log(typeof numberObject); // ???
- console.log(numberObject instanceof Object); // ???
- console.log(numberObject instanceof Number); // ???
- // 挑戰(zhàn)三
- var stringObject = new Object("abcde");
- console.log(typeof stringObject); // ???
- console.log(stringObject instanceof Object); // ???
- console.log(stringObject instanceof String); // ???
- // 挑戰(zhàn)四,翻轉(zhuǎn)一個(gè)字符串
- // 提示:可以使用數(shù)組的 reverse() 方法
- var reverse = function(str) {
- // 待實(shí)現(xiàn)方法體
- }
- console.log(reverse("hello")); // "olleh"