《JavaScript 闖關(guān)記》之基本包裝類型

為了便于操作基本類型值,JavaScript 還提供了3個(gè)特殊的引用類型:Boolean、NumberString。實(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)用了 s1substring() 方法,并將返回的結(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)完成下列處理。

  1. 創(chuàng)建 String 類型的一個(gè)實(shí)例;
  2. 在實(shí)例上調(diào)用指定的方法;
  3. 銷毀這個(gè)實(shí)例。

可以將以上三個(gè)步驟想象成是執(zhí)行了下列 JavaScript 代碼。

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;

經(jīng)過此番處理,基本的字符串值就變得跟對(duì)象一樣了。而且,上面這三個(gè)步驟也分別適用于 BooleanNumber 類型對(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、NumberString 來創(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ù)并傳入 truefalse 值。

var booleanObject = new Boolean(true);

Boolean 類型的實(shí)例重寫了 valueOf() 方法,返回基本類型值 truefalse;重寫了 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ù)。看下面的例子。

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ì)象一樣。具體來講,就是在使用 typeofinstanceof 操作符測(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()方法要簡(jiǎn)便易行(特別是在拼接多個(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ù),則將字符串的長(zhǎng)度作為結(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ù)值與字符串的長(zhǎng)度相加,substr() 方法將負(fù)的第一個(gè)參數(shù)加上字符串的長(zhǎng)度,而將負(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ù)語(yǔ)言(如土耳其語(yǔ))會(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"

一般來說,在不知道自己的代碼將在哪種語(yǔ)言環(huán)境中運(yùn)行的情況下,還是使用針對(duì)地區(qū)的方法更穩(wěn)妥一些。

字符串的模式匹配方法

String 類型定義了幾個(gè)用于在字符串中匹配模式的方法。第一個(gè)方法就是 match(),在字符串上調(diào)用這個(gè)方法,本質(zhì)上與調(diào)用 RegExpexec() 方法相同。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)的位置

為了簡(jiǎ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。再?gòu)?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ū)(國(guó)家和語(yǔ)言)決定了這個(gè)方法的行為。比如,美國(guó)以英語(yǔ)作為 JavaScript 實(shí)現(xiàn)的標(biāo)準(zhǔn)語(yǔ)言,因此 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"

更多

關(guān)注微信公眾號(hào)「劼哥舍」回復(fù)「答案」,獲取關(guān)卡詳解。
關(guān)注 https://github.com/stone0090/javascript-lessons,獲取最新動(dòng)態(tài)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,692評(píng)論 0 4
  • 為了便于操作基本類型值,ECMAScript 還提供了3 個(gè)特殊的引用類型:Boolean、Number和Stri...
    shanruopeng閱讀 251評(píng)論 0 1
  • (十一) 武剛打電話讓徐玲莉回來家,把自己的想法告訴徐玲莉,讓徐玲莉去找朱新剛的老婆,畢竟女人和女人之間好說...
    甜蜜果閱讀 589評(píng)論 0 2
  • 昨晚上給嬌嬌做了黃油煎三文魚,大概巴掌大一塊兒,煎好后,她原地就吃完了,然后又喂了她炒芥蘭,把外皮撕掉,她拿著咬著...
    linyujing閱讀 312評(píng)論 0 0
  • 你是一個(gè)孤獨(dú)的游子 可是你卻走進(jìn)我的心 悄悄的來靜靜的住下 你沒有發(fā)現(xiàn)可是我卻入了戲 在我最美且最懵懂的年紀(jì)遇到你...
    佳兒最美閱讀 72評(píng)論 0 0

友情鏈接更多精彩內(nèi)容