一、基本包装类型的概念
- 基本概念
为了便于操作基本数据类型,ECMAScript
还提供了3
个特殊的引用数据类型:Boolean
、Number
和String
。
在实际中,我们每读取一个基本数据值的时候,后台就会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法操作这些数据。
var s1 = "some text";
var s2 = s1.substring(2);
// 后台会发生以下事情:
// 1、String类型的一个实例;
// 2、在实例中调用指定的方法;
// 3、销毁这个实例。
// 可以将以上三个步骤想像成是执行以下ECMAStript代码。
var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;
- 注意点
(1)引用类型与基本包装类型的区别,在于它们的对象生命周期不同:
- 引用类型:使用
new
创建引用类型的实例,在执行数据流离开当前作用域时会一直存储在内存中。- 基本包装类型:自动创建基本包装类型的对象,只执行一行代码的瞬间之后就会立即销毁。这意味着在运行时为基本包装类型值添加属性和方法是无效的。
(2)使用 new
调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。
var value = "25";
var number = Number(value); // 转型函数,变量number中保存的是基本类型的值 25
alert(typeof number); // "number"
var obj = new Number(value); // 构造函数,变量obj中保存的是Number的实例
alert(typeof obj); // "object"
二、Boolean
类型
Boolean
类型是与布尔值对应的引用类型。Boolean
对象用于将一个不是Boolean
类型的值转换为Boolean
类型值(true
或者false
)。
- 创建
Boolean
对象
// 定义了一个名为 myBoolean 的布尔对象
var booleanObject = new Boolean(true);
如果布尔对象无初始值或者其值为:0
、-0
、null
、""
、false
、undefined
、NaN
,那么对象的值为false
,否则,其值为true
(即使当自变量为字符串"false"
时)!
- 基本类型与引用类型的布尔值的区别
(1)在布尔表达式中使用 Boolean
对象
var falseObject = new Boolean(false);
var result = falseObject && true;
alert(result); // true
var falseValue = false;
result = falseValue && true;
alert(result); // false
特别注意:在布尔表达式中,所有的对象都会被转换为true
。引用类型的布尔值,其实是对象,所以在布尔表达式中使用Boolean
对象都会返回为true
。
所以,不推荐用引用类型的布尔值来判断布尔表达式。
(2)使用 typeof
操作符
// typeof 操作符对基本类型返回"boolean", 而对引用类型返回"object"。
var falseObject = new Boolean(false);
alert(typeof falseObject); // object
var falseValue = false;
alert(typeof falseValue); // boolean
(3)使用 instanceof
操作符
由于 Boolean
对象是 Boolean
类型的实例,所以使用 instanceof
操作符测试 Boolean
对象会返回 true
,而测试基本类型的布尔值则返回 false
。
var falseObject = new Boolean(false);
alert(falseObject instanceof Boolean); // true
var falseValue = false;
alert(falseValue instanceof Boolean); // false
- 常用方法
(1)toString()
方法
功能:根据布尔值返回字符串 "true"
或"false"
。
注释:在 Boolean
对象被用于字符串环境中时,此方法会被自动调用。
var falseObject = new Boolean(false);
var falseString = falseObject .toString();
console.log(falseString ); // "false"
console.log("The falseObject's value is " +falseObject ); // The falseObject's value is false
(2)valueOf()
方法
功能:返回 Boolean
对象的原始值,也就是返回基本类型值 true
或 false
。
var falseObject = new Boolean(false);
var falseString = falseObject .valueOf();
console.log(falseString ); // false
三、Number
类型
- 创建
Number
对象
Number
类型是数字值创建的引用类型。创建Number
类型,使用Number
类型的构造函数,可以传递数字值参数:
var numberObject = new Number(10);
- 常用方法
(1)toFixed()
方法
Number
类型的toFixed()
方法可以接受一个数值,表示保留的小数的个数(会自动四舍五入)。在平时项目中,我们经常要处理价格问题或者增长率问题,即保留多少为小数,用这个方法非常有效。
// Number 类型
var numberObj = new Number(1024.153);
console.log(numberObj.toFixed(2));// 1024.15
console.log(numberObj.toFixed(1));// 1024.2
var num = 10;
alert(num.toFixed(2)); // "10.00"
(2)toString()
方法
toString()
方法将Number
数值转换为字符串,该方法接受一个可选参数基数,告诉它返回几进制数值的字符串形式,若省略该参数,则默认基数为10
,即十进制。
var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"
(3)valueOf()
方法
valueOf()
返回一个 Number
对象的基本数字值。
var num = 10;
alert(num.valueOf()); // 10
- 基本类型与引用类型的数字值的区别
var numberObject = new Number(10);
var numberValue = 10;
// 在使用 typeof 操作符测试基本类型数值时,始终会返回"number"
// 而在测试 Number 对象时, 则会返回"object"。
alert(typeof numberObject); // "object"
alert(typeof numberValue); // "number"
// Number 对象是 Number 类型的实例,而基本类型的数值则不是。
alert(numberObject instanceof Number); // true
alert(numberValue instanceof Number); // false
四、String
类型
- 创建
String
对象
String
类型是字符串值创建的引用类型。String
类型创建的方式,使用String
构造函数创建,可以传入字符串参数:
var stringObject = new String("hello world");
String
对象的属性
String
类型的每个实例都有一个 length
属性,表示字符串中包含多个字符。
var stringValue = "hello world";
alert(stringValue.length); // "11"
String
对象的方法
(1)字符方法
charAt()
和charCodeAt()
两个方法都接收一个参数,即基于0
的字符位置。charAt()
:以单字符字符串的形式返回给定位置的那个字符;charCodeAt()
:返回给定位置的那个字符的字符编码。
var stringValue = "hello world";
alert(stringValue.charAt(1)); // "e"
alert(stringValue.charCodeAt(1)); // 输出"101" (小写字母"e"的字符编码)
// 在支持ES5的浏览器中,可以用方括号[]来访问字符串中某个字符
alert(stringValue[1]); // "e"
(2)字符串操作方法
a、拼接字符串的concat()
方法
concat()
:用于将一或多个字符串拼接起来,返回拼接得到的新字符串。- 实践中,我们平时用的多的还是用
"+"
去拼接字符串。
var stringValue = "hello ";
var result = stringValue.concat("world");
alert(result); //"hello world"
alert(stringValue); //"hello"
// `concat()`方法可以接受任意多个参数,可以通过它拼接任意多个字符串
var stringValue = "hello ";
var result = stringValue.concat("world", "!");
alert(result); //"hello world!"
alert(stringValue); //"hello"
b、三个截取字符串的方法:slice()
、substr()
和 substring()
slice()
跟substring()
非常类似,第一个参数都是截取的起始位置,第二个参数是截取的终止位置;substr()
第一个参数是起始位置,第二个参数则是需要截取的长度。- 这三个函数,都不改变原本的字符串,只是在原先的字符串上创建了一个副本,返回操作副本后的值。
var stringValue = "hello world";
alert(stringValue.slice(3)); //"lo world"
alert(stringValue.substring(3)); //"lo world"
alert(stringValue.substr(3)); //"lo world"
alert(stringValue.slice(3, 7)); //"lo w"
alert(stringValue.substring(3,7)); //"lo w"
alert(stringValue.substr(3, 7)); //"lo worl"
在传递给这些方法的参数是负值的情况下,它们的行为就不尽相同了。
slice()
方法会将传入的负值与字符串的长度相加;substr()
方法将负的第一个参数加上字符串的长度,而将负的第二个参数转换为 0;substring()
方法会把所有负值参数都转换为 0。
var stringValue = "hello world";
alert(stringValue.slice(-3)); //"rld"
alert(stringValue.substring(-3)); //"hello world"
alert(stringValue.substr(-3)); //"rld"
alert(stringValue.slice(3, -4)); //"lo w"
alert(stringValue.substring(3, -4)); //"hel"
alert(stringValue.substr(3, -4)); //""(空字符串)
(3)字符串位置方法
indexOf()
方法从索引0
的位置开始查询子字符串;lastIndexOf()
方法从最后一个索引开始查找字符串;- 如果找到,则返回子字符串的位置,如果没有找到,返回
-1
;- 都接受两个参数,第一个参数为要查找的子字符串,第二个参数可选的,如果有,则表示从某个位置开始查找。
var stringValue = "hello world";
alert(stringValue.indexOf("o")); //4
alert(stringValue.lastIndexOf("o")); //7
alert(stringValue.indexOf("o", 6)); //7
alert(stringValue.lastIndexOf("o", 6)); //4
(4)trim()
方法
trim()
方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果。
var stringValue = " hello world ";
var trimmedStringValue = stringValue.trim();
alert(stringValue); //" hello world "
alert(trimmedStringValue); //"hello world"
trimLeft()
和 trimRight()
方法,分别用于删除字符串开头和末尾的空格。
(5)字符串大小写转换方法
字符串大小写转换的方法:toLowerCase()
、toUpperCase()
。
var stringValue = "hello world";
alert(stringValue.toUpperCase()); //"HELLO WORLD"
alert(stringValue.toLowerCase()); //"hello world"
(6)字符串的模式匹配方法
a、match()
方法
- 在字符串上调用
match()
方法,本质上与调用RegExp
的exec()
方法相同;match()
方法只接受一个参数,要么是一 个正则表达式,要么是一个RegExp
对象;- 返回值:存放匹配结果的数组。该数组的内容依赖于
regexp
是否具有全局标志g
。
如果 regexp
没有标志 g
,那么 match()
方法就只能在 stringObject
中执行一次匹配。
如果没有找到任何匹配的文本, match()
将返回 null
。
否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。
该数组的第 0
个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。
除了这些常规的数组元素之外,返回的数组还含有两个对象属性。
index
属性声明的是匹配文本的起始字符在 stringObject
中的位置;
input
属性声明的是对stringObject
的引用。
var s = 'hello21 world21';
console.log(s.match(/\d{2}/)); // [ '21', index: 5, input: 'hello21 world21' ]
如果 regexp
具有标志 g
,则 match()
方法将执行全局检索,找到 stringObject
中的所有匹配子字符串。
若没有找到任何匹配的子串,则返回 null
。
如果找到了一个或多个匹配子串,则返回一个数组。
不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject
中所有的匹配子串,而且也没有 index
属性或 input
属性。
var s = 'hello21 world21';
console.log(s.match(/\d{2}/g)); //[ '21', '21' ]
b、search()
方法
search()
方法也只接受一个参数,要么是一 个正则表达式,要么是一个RegExp
对象;search()
方法返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回-1
;search()
方法始终是从字符串开头向后查找模式。
var text = "cat, bat, sat, fat";
var pos = text.search(/at/);
alert(pos); //1 ,"at"在字符串中第一次出现的位置
c、replace()
方法
replace()
方法接受两个参数:第一个参数可以是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数;- 如果第一个参数是字符串,那么只会替换第一个子字符串;
- 要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局(
g
)标志。
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"
- 如果
replace()
方法的第二个参数是字符串,那么还可以使用一些特殊的字符序列,将正则表达式操作得到的值插入到结果字符串中。这些特殊的字符序列如下:
字符序列 | 替换文本 |
---|---|
$$ |
$ |
$& |
匹配整个模式的子字符串。与RegExp.lastMatch 的值相同 |
$' |
匹配的子字符串之前的子字符串。与RegExp.leftContext 的值相同 |
$` | 匹配的子字符串之后的子字符串。与RegExp.rightContext 的值相同 |
$n |
匹配第n 个捕获组的子字符串,其中n 等于0~9 。例如,$1 是匹配第一个捕获组的子字符串,$2 是匹配第 二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串 |
$nn |
匹配第nn 个捕获组的子字符串,其中nn 等于01~99 。例如,$01 是匹配第一个捕获组的子字符串,$02 是匹配第二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串 |
// 通过特殊的字符序列,可以使用最近一次匹配结果中的内容
var text = "cat, bat, sat, fat";
result = text.replace(/(.at)/g, "word ($1)");
alert(result); //word (cat), word (bat), word (sat), word (fat)
replace()
方法的第二个参数也可以是函数;- 在只有一个匹配项(即与模式匹配的字符串)的 情况下,会向这个函数传递
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>
d、split()
方法
split()
个方法可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。- 分隔符可以是字符串,也可以是一个
RegExp
对象(这个方 法不会将字符串看成正则表达式)。split()
方法可以接受可选的第二个参数,用于指定数组的大小,以便确保返回的数组不会超过既定大小。
var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(","); //["red", "blue", "green", "yellow"]
var colors2 = colorText.split(",", 2); //["red", "blue"]
var colors3 = colorText.split(/[^\,]+/); //["", ",", ",", ",", ""]