1、基本包装类型介绍
为了便于操作基本类型值,ECMAScript 提供了 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
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"