JavaScript引用类型——“基本包装类型”的注意要点
基本包装类型
为了操作的遍历,ECMAScript 还提供了3 个特殊的引用类型: Boolean、Number 和String。引用类型和基本包装类型的主要区别就是对象的生存期。自动创建的基本包装类型的对象只存在于一行代码的执行瞬间,随后就会被销毁。
另外,Object 构造函数也会根据传入值的类型返回相应基本包装类型的实例。如:
var str = new Object("text");document.write(typeof str); //objectdocument.write(str instanceof String); //true
使用new 调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。如:
var num1 = new Number("321"); //构造函数document.write(num1 instanceof Number); //truedocument.write(typeof num1); //objectvar str = "321";var num2 = Number(str); //转型函数document.write(num2 instanceof Number); //falsedocument.write(typeof num2); //number
Boolean 引用类型
Boolean 引用类型与布尔值对应。可以传入布尔值,语法如下:
var booleanObject = new Boolean(true);//或var booleanObject = new Boolean(false);
该引用类型的实例会修改valueOf()
和toString()
方法。前者返回基本类型值true 和false;后者返回字符串"true" 和"false"。
使用Boolean 引用类型会产生在布尔表达式中使用Boolean 对象。如:
var booleanObj = new Boolean(false);var booleanValue = false;document.write(booleanObj && true); //truedocument.write(booleanValue && true); //false
布尔表达式中的所有对象都会被转换为true。所以建议永远不要使用Boolean 对象。
Number 引用类型
可以调用Number 构造函数向其传入相应的数值。如:
var num = new Number(10);
Number 类型也重写了valueOf()
、toLocaleString()
和toString()
方法。重写后的valueOf()
方法返回对象表示的基本类型的数值。
var num = new Number(10);document.write(typeof num.valueOf()) //number
其中,toFixed()
方法会按照指定的小数位返回数值的字符串表示,如:
var num = new Number(10);document.write(num.toFixed(2)); //10.00
该方法很适合处理货币值。但不同的浏览器给这个方法设定的舍入规则有所不同。IE8 以及之前的版本,在给toFixed()
传入0 的情况下,不能正确舍入范围在{[-0.94,-0.5],[0.5,0.94]}之间的值。IE9 修复了这个问题。
var num = new Number(10);document.write(num.toFixed(21)); //RangeError: toFixed() argument must be between 0 and 20
toFixed()
方法可以表示带有0 到20 个小数位的数值。
另外,toExponential()
方法可以返回以指数表示法(也称e 表示法)表示的数值的字符串形式。如:
var num = 143210000000;document.write(num.toExponential(3)); //1.432e+11
最后,toPrecision()
方法可能会返回固定大小(fixed)格式,也可能返回指数(exponential)格式;它会根据要处理的数值决定到底是调用toFixed()
还是调用toExponential()
。如:
var num = 123;document.write(num.toFixed(1)); //123.0document.write(num.toExponential(2)); //1.23e+2document.write(num.toPrecision(1)); //1e+2document.write(num.toPrecision(3)); //123document.write(num.toPrecision(4)); //123.0
toPrecision()
方法可以表现1 到21 位小叔。某些浏览器支持的范围更大。
仍然不建议直接实例化Number 引用类型,原因与Boolean 对象一样。如:
var num1 = new Number(10);var num2 = 10;console.log(num1); //Numberconsole.log(num2); //10console.log(typeof num1); //objectconsole.log(typeof num2); //numberconsole.log(num1 instanceof Number); //trueconsole.log(num2 instanceof Number); //false
String 引用类型
String 类型是字符串的对象包装类型。创建方法如下:
var str = new String("Hello World");
继承的valueOf()
、toLocaleString()
和toString()
方法,都返回对象所表示的基本字符串值。且每个实例都有一个length 属性。如:
var str = new String("Hello World");document.write(str.length); //11
String类型的方法
String 类型提供了很多方法,用于辅助完成对ECMAScript 中字符串的解析和操作。
字符方法
主要有两个用于访问字符串中特定字符的方法:charAt()
和charCodeAt()
,和一个ECMAScript 5 中的方括号表示法。
charAt()
方法
该方法以单字符串的形式返回给定位置的那个字符(ECMAScript 没有字符类型)。如:
var num = "Hello world";console.log(num.charAt(6)); //w
charCodeAt()
方法
该方法返回字符编码。如:
var num = "Hello world";console.log(num.charCodeAt(6)); //119
方括号表示法(ECMAScript 5)
如果在IE7 及更早版本中使用这种语法,会返回undefined 值。如:
var num = "Hello world";console.log(num[6]); //w
字符串操作方法
拼接、删除等方法
concat()
方法
该方法用于将一个或多个字符串拼接起来。如:
var str = "hello";var newStr = str.concat(" world","!");document.write(str); //hellodocument.write(newStr); //hello world!
实践中,这种方法复杂麻烦不如+ 加号来的方便。
slice()
方法
1 个或2 个参数,第一个参数是开始的位置,第二个参数是结束的位置。如:
var str = "hello world";var newStr = str.slice(5,7);document.write(str + "<br/>" + newStr); //w
substr()
方法
1 个或2 个参数,第一个参数是开始的位置,第二个参数是返回的字符的个数。如:
var str = "hello world";var newStr = str.substr(6, 1);document.write(str + "<br/>" + newStr); //w
substring()
方法
1 个或2 个参数,第一个参数是开始的位置,第二个参数是结束的位置。如:
var str = "hello world";var newStr = str.substring(6, 7);document.write(str + "<br/>" + newStr); //w
以上三个方法在被传入负数的情况下,返回的结果就不太相同了。
slice()
方法会将两个参数与字符串长度相加;substr()
方法会将第一个参数与字符串长度相加,第二个参数转换为0;substring()
方法会将两个参数都转换为0;
如下:
var str = "hello world";var newStr = str.slice(-6, -1);document.write(str + "<br/>" + newStr); //hello world worlvar str = "hello world";var newStr = str.substr(3, -4);document.write(str + "<br/>" + newStr); //" "var str = "hello world";var newStr = str.substring(3,-4); //实际上这个方法会把-4 转换成0,而该方法会从两个参数中较小的一个作为开始位置,所以相当于调用了str.substring(0,3)document.write(str + "<br/>" + newStr); //hello world hel
字符串位置方法
有两个方法:indexOf()
和lastIndexOf()
;该两个方法如果没有找到该子字符串,则返回-1。
indexOf()
方法
indexOf()
方法从字符串的开头向后搜索。如:
var str = "hello world";document.write(str.indexOf("o")); //4
也可以传入第二个参数,即从何处开始。如:
var str = "hello world";document.write(str.indexOf("o",5)); //7
lastIndexOf()
方法
lastIndexOf()
方法从字符串的后面开始向前搜索。如:
var str = "hello world";document.write(str.lastIndexOf("o")); //7
当然也有第二个参数。如:
var str = "hello world";document.write(str.lastIndexOf("o",5)); //4
可以循环调用上面的方法,来找到所有匹配的字符串。如:
var str = "hello world";var pos = str.indexOf("o");var result = [];while (pos > -1){ result.push(pos); pos = str.indexOf("o",pos + 1);}document.write(result.join(" ")); //4 7
trim()
方法
这个方法会创建一个字符串的副本,删除前置和后缀的所有空格,然后返回结果。如:
var str = " hello world ";console.log(str); //" hello world "var newStr = str.trim();console.log(newStr); //"hello world"
字符串大小写转换方法
主要有四个方法:toLowerCase()
、toUpperCase()
、toLocaleLowerCase()
、toLocaleUpperCase()
。其中后面两种方法是针对特定地区的实现。对有些少数语言地区会为Unicode 大小写转换应用特殊的规则。所以,在不知道自己的代码将在哪种语言环境中运行的情况下,还是使用后两种方法比较好。如:
var str = "Apple.Inc";console.log(str.toUpperCase());console.log(str.toLowerCase());console.log(str.toLocaleUpperCase());console.log(str.toLocaleLowerCase()); /*[Log] APPLE.INC (repetition.html, line 16)[Log] apple.inc (repetition.html, line 17)[Log] APPLE.INC (repetition.html, line 18)[Log] apple.inc (repetition.html, line 19)*/
字符串的模式匹配方法
有四个方法:match()
、search()
、replace()
、split()
。
match()
方法
本质上与调用RegExp 的exec()
方法相同。match()
方法接受一个参数(正则表达式或RegExp 对象)如:
var str = "red hed bed led";var pattern = /.ed/;var matches = str.match(pattern); //与pattern.exec(str)相同console.log(matches); //["red"]
search()
方法
唯一的参数与match()
方法相同。search()
方法返回字符串中第一个匹配项的索引;如果没有就返回-1;如:
var str = "red hed bed led";var pattern = /ed/;var matched = str.search(pattern);console.log(matched); //1
replace()
方法
接收两个参数:第一个是RegExp 对象或者一个字符串;第二个参数是字符串或者一个函数。
如果第一个参数是字符串,就会替换第一个子字符串。如:
var str = "red hed bed led";var matched = str.replace("red", "aaa");console.log(matched); //aaa hed bed led
如果第一个参数是正则表达式且指定了全局g 标志,就会替换所有。如:
var str = "red hed bed led";var matched = str.replace(/ed/g, "aaa,");console.log(matched); //raaa, haaa, baaa, laaa,
如果第二个参数是字符串,那么可以使用一些特殊的字符序列:
$$ (替换成$)
$&(匹配整个模式的子字符串)
$` (匹配的子字符串之前的子字符串)
$' (匹配的子字符串之后的子字符串)
$n (匹配第n 个捕获组的子字符串)
$nn (匹配第nn 个捕获组的子字符串)
如:
var str = "red hed bed led";var matched = str.replace(/ed/g, "$$-"); //r$- h$- b$- l$-matched = str.replace(/ed/g, "$&-"); //red- hed- bed- led-matched = str.replace(/.ed/g, "$`-"); //- red - red hed - red hed bed -matched = str.replace(/.ed/g, "$'-"); //hed bed led- bed led- led- -matched = str.replace(/(ed)/g, "$1ing"); //reding heding beding ledingconsole.log(matched);
如果第二个参数是一个函数,这个函数会被传递多个参数:模式的匹配项、第一个捕获组的匹配项、第二个...,最后两个参数是分别是模式的匹配项在字符串中的位置和原始字符串。如:
function inputText(text){ return text.replace(/[lo]/g, function(match,pos,orignalText){ switch(match){case "l":return "1";case "o":return "0"; } });}var output = inputText("hello");console.log(output); //he110
split()
方法
这个方法可以基于指定的分隔符将一个字符串分割成多个字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以是一个RegExp 对象。第二个参数是可选的,用于指定数组的大小。如:
var str = "Apple.Inc,Baidu.Inc,Alibaba.Inc";var list = str.split(",");document.write(list.join(" & ")); //Apple.Inc & Baidu.Inc & Alibaba.Incconsole.log(list); //["Apple.Inc", "Baidu.Inc", "Alibaba.Inc"]
localeCompare()
方法
这个方法是比较两个字符串,并返回下列值中的一个:
如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(多数情况下是-1);
如果字符串在字母表中应该排在字符串参数之后,则返回一个正数(多数情况下是1);
如果字符串等于字符串参数,则返回0;
具体如下:
var strValue = "hello";console.log(strValue.localeCompare("world")); //-1 字符串hello 在字符串参数world 之前,返回-1console.log(strValue.localeCompare("Alice")); //1console.log(strValue.localeCompare("hello")); //0
因为返回的数值不一定上上面三种,所以最好用下面这个方法比较:
function compare(x,y){ var result = x.localeCompare(y); if (result > 0){ document.write(y + "," + x); }else if(result < 0){ document.write(x + "," + y); }else{ document.write("equal"); }}compare("apple","baidu"); //apple,baidu
可以尝试把string 转换成array 再用数组重排序的方法:
str = "blue,red,yellow,white";function compare(str){ var strArray = str.split(","); var newStrArray = strArray.sort(arraySortFunc); function arraySortFunc(a,b){ if (a > b){return 1; }else if(a < b){return -1; }else{return 0; } } console.log(newStrArray); //["blue", "red", "white", "yellow"]}compare(str);
fromCharCode()
方法
这是一个静态方法。目的是接收一个或多个字符编码,然后将他们转换成一个字符串。从本质上来看这个方法与charCodeAt()
执行的是相反的操作。注意他的语法是String.charCodeAt()
如:
function consoleStrCode(str){ var codeStr = ""; var codeArray = []; for (var i = 0; i < str.length; i ++){ var codeValue = str.charCodeAt(i); codeStr += codeValue + ","; } codeArray = codeStr.split(","); codeArray.pop(); console.log(codeArray);}consoleStrCode("hello"); //["104", "101", "108", "108", "111"]function consoleCodeStr(codeArray){ var codeStr = ""; for (var i = 0;i < codeArray.length;i ++){ var currentCode = codeArray[i]; var currentCodeValue = parseInt(currentCode); codeStr += String.fromCharCode(currentCodeValue); } console.log(codeStr);}var codeArray = ["104", "101", "108", "108", "111"];consoleCodeStr(codeArray); //hello
以上代码就是代码和字符串互换的函数。
HTML 方法(避免使用)
该方法的目的是简化常见的HTML 格式化。因为它们创建的标记通常无法表达语义。所以应该避免使用。