JS”包装类“详解

89 阅读5分钟

在JavaScript的世界里,包装类(Wrapper Objects)扮演着连接原始值(Primitive Values)与对象世界桥梁的角色,它们使得原始值能够临时具备对象的特性,如拥有属性和方法。本文将深入探讨JavaScript中的包装类概念、其工作原理、以及它们如何影响我们编写代码的方式。同时,我们也会简要回顾对象的基本概念,特别是创建对象的不同方式,最后结合new操作符的机制,来全面理解这些核心概念在JavaScript编程中的应用。

JavaScript中的原始值与包装类

原始值概述

JavaScript中有五种基本的数据类型,被称为原始值或基本数据类型:undefinednullbooleannumber、和string。原始值是不可变的,意味着一旦创建,其值就不能被改变。由于它们不是对象,理论上不能直接为它们添加属性或方法。

包装类的作用

为了克服原始值不能直接操作属性和方法的限制,JavaScript提供了三种包装对象:BooleanNumber、和String。这些包装类能够在需要时动态地将原始值转换为对象,从而允许我们像操作对象那样操作原始值,比如调用方法或添加属性。然而,这种转换是临时的,并且一旦操作完成,包装对象就会被销毁,以保持原始值的不可变性。

包装类的工作原理

当尝试访问原始值的属性或方法时,JavaScript引擎会自动进行以下步骤:

  1. 创建包装对象:引擎会创建对应类型的包装对象(例如,对于字符串,会创建String对象)。
  2. 执行操作:通过这个临时的对象执行所需的操作,比如调用方法或设置属性。
  3. 销毁对象:操作完成后,包装对象会被销毁,确保原始值的纯净性和不可变性。

valueOf与原始值的试探

JavaScript的包装类实现了valueOf方法,用于返回原始值。当执行环境探测到对包装类的直接使用(如试图读取或设置属性),它首先通过valueOf检查是否能还原为原始值。如果可以,操作将基于原始值进行,任何尝试在此临时对象上添加的属性都会被忽略,因为最终这个临时对象会被销毁,以此维护原始值的规则。

image.png

image.png

一个案例理解包装类

var str ='abc' 
str +=1 
var test =typeof(str)   
if(test.length===6){
    test.sign='typeOf 的返回结果可能是String'  
}
console.log(test.sign); 

这是一道面试题,问我们输出结果是什么。

第一行代码创建了一个字符串str ,在v8看来这是new了一个String{}——var str=new String(), 第二行代码是进行字符拼接,v8先进行判断,将字符串对象转换为原始值——str.valueOf(),如果能转换成原始值,这就说明程序员一开始创建的不是一个字符串对象而是一个字符串,将字符串对象中的字符串,拿出来进行拼接操作。

第三行是判断str的类型,并返回给变量test

第四行是进行判断,判断test长度,

第五行是给test变量增加属性,一样的,在v8看来,字符串第三行的代码等于var test=new String(typeof(str)),创建的是一个字符串对象,所以可以给他增加属性。

第六行输出结果,因为test可以转换成原始值,所以程序员一开始创建的是一个字符串变量,而不是一个对象,变量是不能具有属性和方法的,所以将添加的属性移除,输出结果为undefined,有添加这属性,但是这个属性被移除了。

image.png

对象的创建方式

理解了包装类的概念后,我们来看看JavaScript中创建对象的几种常见方式:

对象字面量

最直接且简洁的方式,通过键值对的形式定义对象。

let obj = { key: 'value' };

new Object()

利用构造函数创建一个空对象,随后可以为其添加属性和方法。

let obj = new Object();
obj.key = 'value';

构造函数

自定义构造函数或使用内置构造函数(如Array, Date等)创建对象。

function Person(name) {
    this.name = name;
}

let person = new Person('Alice');

new操作符的机制

在JavaScript中,new关键字用于实例化对象,其背后的机制包括三个主要步骤:

  1. 创建新对象new操作符首先会在内存中创建一个新的空对象。
  2. 绑定原型:接着,这个新对象的[[Prototype]](内部属性)会被设置为构造函数的prototype属性所指向的对象。
  3. 执行构造函数:构造函数会被调用,this关键字在构造函数内部指代新创建的对象。任何使用this分配的属性或方法都将附加到这个新对象上。
  4. 返回对象:如果构造函数没有明确返回一个对象,那么new操作符会默认返回这个新创建的对象。

结论

包装类的存在让JavaScript在保持原始值不变性的前提下,赋予了原始值短暂的“对象”能力,这不仅丰富了语言的表达能力,也让开发者能够以更加灵活的方式处理数据。理解对象的创建方式,尤其是new操作符的机制,对于深入掌握JavaScript面向对象编程至关重要。通过这些基础知识的学习,开发者可以更有效地利用JavaScript的强大功能,编写出既高效又易于维护的代码。