【JavaScript 教程】标准库—包装对象

作者 | 阮一峰



定义

对象是 JavaScript 语言最主要的数据类型,三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”。

所谓“包装对象”,就是分别与数值、字符串、布尔值相对应的NumberStringBoolean三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。

var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);

上面代码中,基于原始类型的值,生成了三个对应的包装对象。

typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"

v1 === 123 // false
v2 === 'abc' // false
v3 === true // false

包装对象的最大目的,首先是使得 JavaScript 的对象涵盖所有的值,其次使得原始类型的值可以方便地调用某些方法。

NumberStringBoolean如果不作为构造函数调用(即调用时不加new),常常用于将任意类型的值转为数值、字符串和布尔值。

Number(123) // 123
String('abc') // "abc"
Boolean(true) // true

上面这种数据类型的转换,详见《数据类型转换》一节。

总结一下,这三个对象作为构造函数使用(带有new)时,可以将原始类型的值转为对象;作为普通函数使用时(不带有new),可以将任意类型的值,转为原始类型的值。

2、实例方法

三种包装对象各自提供了许多实例方法,详见后文。这里介绍两种它们共同具有、从Object对象继承的方法:valueOftoString

2.1、valueOf()

valueOf方法返回包装对象实例对应的原始类型的值。

new Number(123).valueOf()  // 123
new String('abc').valueOf() // "abc"
new Boolean(true).valueOf() // true

2.2、toString()

toString方法返回对应的字符串形式。

new Number(123).toString() // "123"
new String('abc').toString() // "abc"
new Boolean(true).toString() // "true"

3、原始类型与实例对象的自动转换

原始类型的值,可以自动当作包装对象调用,即调用包装对象的属性和方法。这时,JavaScript 引擎会自动将原始类型的值转为包装对象实例,在使用后立刻销毁实例。

比如,字符串可以调用length属性,返回字符串的长度。

'abc'.length // 3

上面代码中,abc是一个字符串,本身不是对象,不能调用length属性。JavaScript 引擎自动将其转为包装对象,在这个对象上调用length属性。调用结束后,这个临时对象就会被销毁。这就叫原始类型与实例对象的自动转换。

var str = 'abc';
str.length // 3

// 等同于
var strObj = new String(str)
// String {
// 0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"
// }
strObj.length // 3

上面代码中,字符串abc的包装对象提供了多个属性。

自动转换生成的包装对象是只读的,无法修改。所以,字符串无法添加新属性。

var s = 'Hello World';
s.x = 123;
s.x // undefined

上面代码为字符串s添加了一个x属性,结果无效,总是返回undefined

另一方面,调用结束后,包装对象实例会自动销毁。这意味着,下一次调用字符串的属性时,实际是调用一个新生成的对象,而不是上一次调用时生成的那个对象,所以取不到赋值在上一个对象的属性。如果要为字符串添加属性,只有在它的原型对象String.prototype上定义(参见《面向对象编程》章节)。

4、自定义方法

除了原生的实例方法,包装对象还可以自定义方法和属性,供原始类型的值直接调用。

比如,我们可以新增一个double方法,使得字符串和数字翻倍。

String.prototype.double = function () {
return this.valueOf() + this.valueOf();
};

'abc'.double()
// abcabc

Number.prototype.double = function () {
return this.valueOf() + this.valueOf();
};

(123).double()
// 246

上面代码在123外面必须要加上圆括号,否则后面的点运算符(.)会被解释成小数点。

但是,这种自定义方法和属性的机制,只能定义在包装对象的原型上,如果直接对原始类型的变量添加属性,则无效。

var s = 'abc';
s.p = 123;
s.p // undefined

上面代码直接对字符串abc添加属性,结果无效。主要原因是上面说的,这里的包装对象是自动生成的,赋值后自动销毁,所以最后一行实际上调用的是一个新的包装对象。


本章节完


推荐阅读系列章节

【JavaScript 教程】入门篇-导论

【JavaScript 教程】入门篇-JavaScript 语言的历史

【JavaScript 教程】入门篇-JavaScript 的基本语法

【JavaScript 教程】数据类型-概述

【JavaScript 教程】数据类型-null, undefined 和布尔值

【JavaScript 教程】数据类型-数值

【JavaScript 教程】数据类型-字符串

【JavaScript 教程】数据类型-对象

【JavaScript 教程】数据类型-函数

【JavaScript 教程】数据类型-数组

【JavaScript 教程】运算符—算术运算符

【JavaScript 教程】运算符—比较运算符

【JavaScript 教程】运算符—布尔运算符

【JavaScript 教程】运算符—二进制位运算符

【JavaScript 教程】运算符—其他运算符,运算顺序

【JavaScript 教程】语法专题—数据类型的转换

【JavaScript 教程】语法专题—错误处理机制

【JavaScript 教程】语法专题—编程风格

【JavaScript 教程】语法专题—console 对象与控制台

【JavaScript 教程】标准库—Object 对象

【JavaScript 教程】标准库—属性描述对象

【JavaScript 教程】标准库—Array 对象




【JavaScript 教程】标准库—包装对象

【JavaScript 教程】标准库—包装对象

相关文章: