JavaScript:基本包裝類型
為了方便操作,JavaScript提供了3個特殊的引用類型:Boolean、Number和String。實際上,每當讀取一個基本類型值的時候,後臺就會創建一個對應的基本包裝類型的對象,從而可以調用這些類型的方法來操作數據。
var s1 = "hello javascript";
var s2 = s1.substring(2);
在上面的例子中,s1是一個字符串,是基本類型值。而s1調用了substring()方法,理論上基本類型值不是對象,它們不應該有方法的。其實,為了實現這種操作,後臺已經自動完成了一系列的處理。當第二行代碼訪問s1時,會完成下面一系列操作:
- 創建String類型的一個實例;
- 在實例上調用指定的方法;
- 銷毀這個實例
引用類型和基本包裝類型的主要區別就是對象的生存期。使用new操作符創建的引用類型的實例,在執行流離開當前作用域之前都一直保存在內存中。而自動創建的基本包裝類型的對象,則只存在於一行代碼的執行瞬間,然後立即被銷毀。這意味著不能在運行時為基本類型值添加屬性和方法。
var s1 = "hello";
s1.name = "Jack";
alert(s1.name); // undefined
對基本包裝類型的實例調用typeof會返回object,所有基本包裝類型都會被轉換為布爾值true。
Object構造函數會根據傳入值的類型返回相應的基本包裝類型:
var obj1 = new Object("hello");
var obj2 = new Object(12);
var obj3 = new Object(true);
alert(obj1 instanceof String); // true
alert(obj2 instanceof Number); // true
alert(obj3 instanceof Boolean); // true
註意,使用new調用基本包裝類型的構造函數,與直接調用同名的轉型函數不一樣:
var val = "10";
var num = Number(val); // 轉型函數
alert(typeof num); // number
var obj = new Number(val); // 構造函數
alert(typeof obj); // object
Boolean類型
Boolean類型是與布爾值對應的引用類型。創建Boolean類型對象:
var trueObj = new Boolean(true);
var falseObj = new Boolean(false);
Boolean類型的實例重寫了valueOf()方法,返回基本類型值true或false;重寫toString()方法,返回字符“true”或“false”。
在布爾表達式中使用Boolean對象時要特別註意:布爾表達式中的所有對象都會被轉換為true。
var falseObj = new Boolean(false);
var result = falseObj && true; // ①
alert(result); // true
var falseVal = false;
result = falseVal && true; // ②
alert(result); // false
上面的例子中,首先創建了一個false值的Boolean對象falseObj。①處將falseObj與基本類型值true進行&&運算。這裏特別要註意:falseObj會轉換為true。所以結果為true。②處都是基本類型,進行&&運算結果為false,不需要多解釋。
基本類型與引用類型的布爾值還有兩個區別:
- typeof操作符對基本類型返回“boolean”,而引用類型返回“object”
- 使用instanceof操作符測試Boolean對象會返回true,而測試基本類型的布爾值則返回false
看下面的例子:
alert(typeof falseObj); // object
alert(typeof falseVal); // boolean
alert(falseObj instanceof Boolean); // true
alert(falseVal instanceof Boolean); // false
Number類型
Number是與數字值對應的引用類型。創建Number類型對象:
var numObj = new Number(100);
Number類型重寫了valueOf()、toLocaleString()和toString()方法,重寫後valueOf()返回對象表示的基本類型的數值,另外兩個方法會返回字符串形式的數值。
var num = 11;
alert(num.toString()); // "11"
alert(num.toString(2)); // "1011"
alert(num.toString(8)); // "13"
alert(num.toString(10)); // "11"
alert(num.toString(16)); // "b"
另外,Number提供了一些將數值格式化為字符串的方法。
1.toFixed()
toFixed()方法會按照指定的小數位返回值得字符串表示。
var num1 = 11;
alert(num1.toFixed(2)); // "11.00"
var num2 = 11.005;
alert(num1.toFixed(2)); // "11.01"
2.toExponential()
toExponential()方法用於格式化,返回指數表示法,表示的數值的字符串形式。可以傳入一個參數,指定輸出結果中的小數位數。
var num = 11;
alert(num.toExponential(1)); // “1.0e+1”
3.toPrecision()
toPrecision()方法可能返回固定大小格式,也可能返回指數格式。可以接收一個參數,表示數值的所有數字的位數(不含指數部分)
var num = 99;
alert(num.toPrecision(1)); // "1e+2",即100,無法準確表示99
alert(num.toPrecision(2)); // "99"
alert(num.toPrecision(3)); // "99.0"
與Boolean類型相似,使用typeof和instanceof操作基本類型數值和引用類型數值時,得到的結果完全不同。
var numObj = new Number(11);
var numVal = 11;
alert(typeof numObj); // "object"
alert(typeof numVal); // "number"
alert(numObj instanceof Number); // true
alert(numObj instanceof Number); // false
String類型
String類型是字符串的對象包裝類型,創建String類型:
var strObj = new String("hello javascript");
String類型提供了很多方法,用於完成字符串的解析和操作:
1.字符方法
兩個用於訪問字符串中特定字符的方法:charAt()和charCodeAt()。
- charAt():以單字符串的形式返回給定位置的那個字符
- charCodeAt():返回字符的編碼
舉例:
var strVal = "hello";
alert(strVal.char(1)); // "e"
alert(strVal.charCodeAt(1)); // "101"
2.字符串操作方法
- concat():用於將一個或多個字符串拼接起來,返回拼接得到的新字符串,但是原來的字符串不變。
示例:
var strVal = "hello ";
var result = strVal.concat("javascript");
alert(result); // "hello javascript"
alert(strVal); // "hello "
concat()可以接收多個參數:
var result1 = strVal.concat("world", "!")
alert(result1); // "hello world!"
下面的三個方法都返回被操作字符串的子字符串,接收1或2個字符串。不同的是:
- slice():第一個參數表示起始位置,第二個參數表示結束位置(不包含)
- substr():第一個參數表示起始位置,第二個參數表示返回的字符個數(不包含)
- substring():第一個參數表示起始位置,第二個參數表示子字符串最後一個字符後面的位置(不包含)
示例:
var str = "hello world";
alert(str.slice(3)); // "lo world"
alert(str.slice(3, 7)); // "lo w"
alert(str.substr(3)); // "lo world"
alert(str.substr(3, 7)); // "lo worl"
alert(str.substring(3)); // "lo world"
alert(str.substring(3, 7)); // "lo w"
當參數為負數時,上面的三個方法行為各不相同:
- slice():將傳入的負值與字符串的長度相加
- substr():將負的第一個參數加上字符串的長度,將負的第二個參數轉換為0
- substring():將所有負值參數都轉換為0
示例:
var strVal = "hello world";
alert(strVal.slice(-3)); // "rld"
alert(strVal.substr(-3)); // "rld"
alert(strVal.substring(-3));// "hello world"
alert(strVal.slice(3, -4)); // "lo w"
alert(strVal.substr(3, -4));// ""
alert(strVal.substring(3, -4));// "hel"
下面對第二個參數是負值的情況作出解釋,由於slice()會將第二個負的參數加上字符串的長度,所以
strVal.slice(3,-4)
會轉換為strVal.slice(3, 7)
,因此返回“lo w”。substr()會將第二個參數轉換為0,strVal.substr(3, -4)
會轉換為strVal.substr(3, 0)
,因此返回的是空串。substring()會將第二個負的參數轉換為0,strVal.substring(3, -4)
會轉換為strVal.substring(3, 0)
,但是,substring()會將較小的數作為開始位置,將較大的數作為結束位置,因此,最終轉換為strVal.substring(0, 3)
,所以返回結果為“hel”。
3.字符串位置方法
從字符串查找子字符串的方法:indexOf()
和lastIndexOf()
。它們都從字符串中查找子字符串,返回子字符串的位置(如果沒有找到子字符串,則返回-1),區別在於:
- indexOf()字符串開頭向後搜索子字符串
- lastIndexOf()從字符串的末尾向前搜索子字符串
示例:
var strVal = "hello world";
alert(strVal.indexOf("o")); // 4
alert(strVal.lastIndexOf("o")); // 7
這兩個方法可以接收可選的第二個參數,表示搜索的開始位置。
var strVal = "hello world";
alert(strVal.indexOf("o", 6)); // 7
alert(strVal.lastIndexOf("o", 6)); // 4
在使用第二個參數的情況下,可以通過循環來調用indexOf()或lastIndexOf()來找到所有匹配的子字符串:
var strVal = "Only hard work forever as a necessary of life; even if there is no hope of harvest, but also a calm to continue farming.";
var positions = new Array();
var pos = strVal.indexOf("o");
while(pos > -1) {
positions.push(pos);
pos = strVal.indexOf("o", pos + 1);
}
alert(positions); // 11,16,38,65,68,72,91,101,104
4.trim()
trim()會創建一個字符串的副本,刪除前置及後綴的所有空格,然後返回結果。
var strVal = " hello world ";
var trimStrVal = strVal.trim();
alert(strVal); // " hello world "
alert(trimStrVal); // "hello world"
5.字符串大小寫轉換方法
var strVal = "heLLo woRLd";
alert(strVal.toLocaleUpperCase()); // "HELLO WORLD"
alert(strVal.toUpperCase()); // "HELLO WORLD"
alert(strVal.toLocaleLowerCase()); // "hello world"
alert(strVal.toLowerCase()) // "hello world"
6.字符串模式匹配方法
- match()方法
看一個例子:
var text = "cat, bat, sat, fat";
var pattern = /.at/;
// 與pattern.exec(text)相同
var matches = text.match(pattern);
alert(matches.index); // 0
alert(matches[0]); // "cat"
alert(pattern.lastIndex); // 0
match()接收一個正則表達式,返回一個數組,數組的第一項是與整個模式匹配的字符串,之後的每一項保存著與正則表達式中的捕獲組匹配的字符串。
- search()
search()接收一個正則表達式,返回字符串中第一個匹配項的索引;如果沒有找到匹配項,則返回-1
var text = "cat, bat, sat, fat";
var pos = text.search(/at/);
alert(pos); // 1
- replace()
JavaScript還提供了replace()方法。該方法接收兩個參數,第一個參數是RegExp對象或字符串,第二個參數可以是字符串或一個函數。當第一個參數是一個字符串時,只會替換第一個子字符串。
var text = "cat, bat, sat, fat";
var result = text.replace("at", "ond");
alert(result); // cond, bat, sat, fat
result = text.replace(/at/g, "ond");
alert(result); // cond, bond, sond, fond
當第二個參數是一個函數時,在只有一個匹配項的情況下,會向這個函數傳遞3個參數:模式的匹配項、模式匹配項在字符串中的位置和原始字符串。在正則表達式中定義了多個捕獲組的情況下,傳遞給函數的參數一次是模式的匹配項、第一個捕獲組的匹配項、第二個捕獲組的匹配項……,但
最後兩個參數仍然分別是模式匹配項在字符串中的位置和原始字符串。
function htmlEscape(text) {
return text.replace(/[<>"&]/g, function(match, pos, originalText) {
switch (match) {
case "<":
return "<";
case ">":
return ">";
case "&":
return "&";
case "\"":
return """;
}
});
}
alert(htmlEscape("<p class=\"greeting\">Hello world!</p>"));
// <p class="greeting">Hello world!</p>
- split()
split()可以指定基於指定的分隔符將一個字符串分割成多個子字符串,並將結果放在一個數組中。
var colorText = "red, blue, green, yellow";
var colors1 = colorText.split(",");
alert(colors1); // ["red", "blue", "green", "yellow"]
split()還可以接收可選的第二個參數, 用於指定數組的大小。
var colors2 = colorText.split(",", 2); // ["red", "blue"]
7.localeCompare()方法
localeCompare()用於比較兩個字符串,並返回下列結果之一:
- 如果字符串在字母表中應該排在字符串參數之前,則返回一個負數(多數情況為-1,具體由實現而定)
- 如果字符串等於字符串的參數,則返回0;
- 如果字符串在字母表中應該排在字符串參數之後,則返回一個整數(多數情況為1,具體由實現而定)
下面看一個例子:
var strVal = "yellow";
alert(strVal.localeCompare("brick")); // -1
alert(strVal.localeCompare("yellow")); // 0
alert(strVal.localeCompare("zoo")); // 1
8.fromCharCode()
String構造函數本身有一個靜態方法:fromCharCode()。這個方法的任務是接收一或多個字符編碼,然後將它們轉換成一個字符串。
alert(String.fromCharCode(104, 101, 108, 108, 111)); // "hello"
JavaScript:基本包裝類型