前端JavaScript基础训练系列九十八:封装对象包装

封装对象(object wrapper)扮演着十分重要的角色。由于基本类型值没有 .length 和 .toString() 这样的属性和方法,需要通过封装对象才能访问,此时 JavaScript 会自动为 基本类型值包装(box 或者 wrap)一个封装对象:

var a = "abc";
     a.length; // 3
     a.toUpperCase(); // "ABC"

如果需要经常用到这些字符串属性和方法,比如在for循环中使用i < a.length,那么从 一开始就创建一个封装对象也许更为方便,这样 JavaScript 引擎就不用每次都自动创建了。
但实际证明这并不是一个好办法,因为浏览器已经为 .length 这样的常见情况做了性能优 化,直接使用封装对象来“提前优化”代码反而会降低执行效率。

一般情况下,我们不需要直接使用封装对象。最好的办法是让 JavaScript 引擎自己决定什 么时候应该使用封装对象。换句话说,就是应该优先考虑使用 “abc” 和 42 这样的基本类型 值,而非 new String(“abc”) 和 new Number(42)。
封装对象释疑
使用封装对象时有些地方需要特别注意。 比如 Boolean:

    var a = new Boolean( false );
if (!a) {
console.log( "Oops" ); // 执行不到这里
}

我们为 false 创建了一个封装对象,然而该对象是真值(“truthy”,即总是返回 true,参见
),所以这里使用封装对象得到的结果和使用 false 截然相反。 如果想要自行封装基本类型值,可以使用 Object(…) 函数(不带 new 关键字):

    var a = "abc";
     var b = new String( a );
     var c = Object( a );
     typeof a; // "string"
     typeof b; // "object"
     typeof c; // "object"
     b instanceof String; // true
     c instanceof String; // true
     Object.prototype.toString.call( b ); // "[object String]"
     Object.prototype.toString.call( c ); // "[object String]"

再次强调,一般不推荐直接使用封装对象(如上例中的 b 和 c),但它们偶尔也会派上 用场。

拆封

如果想要得到封装对象中的基本类型值,可以使用 valueOf() 函数:


     var a = new String( "abc" );
     var b = new Number( 42 );
     var c = new Boolean( true );
     a.valueOf(); // "abc"
     b.valueOf(); // 42
     c.valueOf(); // true

在需要用到封装对象中的基本类型值的地方会发生隐式拆封。具体过程(即强制类型转 换)将在第 4 章详细介绍。

var a = new String( "abc" ); var b = a + ""; // b的值为"abc"
     typeof a;       // "object"
     typeof b;       // "string"

原生函数作为构造函数

关于数组(array)、对象(object)、函数(function)和正则表达式,我们通常喜欢以常 量的形式来创建它们。实际上,使用常量和使用构造函数的效果是一样的(创建的值都是 通过封装对象来包装)。
如前所述,应该尽量避免使用构造函数,除非十分必要,因为它们经常会产生意想不到的 结果。

Array(..)
var a = new Array( 1, 2, 3 );
a; // [1, 2, 3]
     var b = [1, 2, 3];
     b; // [1, 2, 3]

构造函数 Array(…) 不要求必须带 new 关键字。不带时,它会被自动补上。 因此 Array(1,2,3) 和 new Array(1,2,3) 的效果是一样的。
Array 构造函数只带一个数字参数的时候,该参数会被作为数组的预设长度(length),而 非只充当数组中的一个元素。

这实非明智之举:一是容易忘记,二是容易出错。 更为关键的是,数组并没有预设长度这个概念。这样创建出来的只是一个空数组,只不过

它的 length 属性被设置成了指定的值。
如若一个数组没有任何单元,但它的 length 属性中却显示有单元数量,这样奇特的数据结 构会导致一些怪异的行为。而这一切都归咎于已被废止的旧特性(类似 arguments 这样的 类数组)。
我们将包含至少一个“空单元”的数组称为“稀疏数组”。
对此,不同浏览器的开发控制台显示的结果也不尽相同,这让问题变得更加复杂。
例如:

    var a = new Array( 3 );
     a.length; // 3
     a;

a在Chrome中显示为 undefined x 3 ,这意味着它有三个值为undefined 的单元,但实际上单元并不存在(“空单元”这个叫法也同样不准确)。

  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值