千家信息网

JavaScript原始值与包装对象介绍

发表于:2025-11-12 作者:千家信息网编辑
千家信息网最后更新 2025年11月12日,这篇文章主要介绍"JavaScript原始值与包装对象介绍",在日常操作中,相信很多人在JavaScript原始值与包装对象介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年11月12日JavaScript原始值与包装对象介绍

这篇文章主要介绍"JavaScript原始值与包装对象介绍",在日常操作中,相信很多人在JavaScript原始值与包装对象介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"JavaScript原始值与包装对象介绍"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

前言

随着 JavaScript 越来越流行,越来越多地开发者开始接触并使用 JavaScript。

同时我也发现,有不少开发者对于 JavaScript 最基本的原始值和包装对象都没有很清晰的理解。

那么本篇文章,就由渣皮来给大家详细介绍一下它们。

话不多说,Let's go!

正文

原始类型 (Primitive types)

原始类型也被称为"基本类型"。

目前在 JavaScript 中有以下几种原始类型:

  • string(字符串)

  • number(数字)

  • boolean(布尔)

  • null(空)

  • undefined(未定义)

  • bigint(大整数,ES6)

  • symbol(标志?ES6)

如下:

typeof 'chenpipi';  // "string" typeof 12345;       // "number" typeof true;        // "boolean" typeof null;        // "object" typeof undefined;   // "undefined" typeof 12345n;      // "bigint" typeof Symbol();    // "symbol"

特别注意

typeof null 虽然返回 "object",但是这不代表 null 就是对象,这其实是 JavaScript 的一个 Bug,且从 JavaScript 诞生以来便如此。

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。

The history of "typeof null":https://2ality.com/2013/10/typeof-null.html

原始值 (Primitive values)

原始值也就是原始类型的值(数据)。

A primitive value is data that is not an object and has no methods.

原始值是一种没有任何方法的非对象数据。

也就是说,string、number 和 boolean 等原始类型的值本身是没有任何属性和方法的。

这个时候嗅觉敏锐的小伙伴是不是已经察觉到有什么不对劲了?

是孜然!我加了孜然!(手动狗头并划掉)

这里有一个非常有意思的点,但是在讨论这个问题之前,先让我们认识下包装对象。

包装对象 (Wrapper objects)

除了 null 和 undefined 外的原始类型都有其相应的包装对象:

  • String(字符串)

  • Number(数字)

  • Boolean(布尔)

  • BigInt(大整数,ES6)

  • Symbol(标志?ES6)

对象 (Object)

对象是引用类型。

首先,包装对象本身是一个对象,也是函数。

String instanceof Object;   // true String instanceof Function; // true

构造函数 (Constructor)

实例 (Instance)

其中 String、Number 和 Boolean 均支持使用 new 运算符来创建对应的包装对象实例。

例如 String 的声明(节选):

interface StringConstructor {   new(value?: any): String;   (value?: any): string;   readonly prototype: String; } declare var String: StringConstructor;

使用 new 运算符得到的数据是对象(Object):

// 字符串 typeof 'pp';                      // "string" typeof new String('pp');          // "object" new String() instanceof Object;   // true // 数字 typeof 123;                       // "number" typeof new Number(123);           // "object" new Number() instanceof Object;   // true // 布尔 typeof true;                      // "boolean" typeof new Boolean(true);         // "object" new Boolean() instanceof Object;  // true

我们可以调用包装对象实例的 valueOf() 函数来获取其原始值:

// 字符串 let s = new String('pp'); s.valueOf();                // "pp" typeof s.valueOf();         // "string" // 数字 let n = new Number(123); n.valueOf();                // 123 typeof n.valueOf();         // "number" // 布尔 let b = new Boolean(true); b.valueOf();                // true typeof b.valueOf();         // "boolean"

"异类" (Attention)

而 BigInt 和 Symbol 都属于"不完整的类",不支持 new 运算符。

例如 BigInt 的声明(节选):

interface BigIntConstructor {   (value?: any): bigint;   readonly prototype: BigInt; } declare var BigInt: BigIntConstructor;

可以看到 BigInt 的声明中没有 new 运算符相关函数。

普通函数 (Function)

包装对象也可以作为普通函数来使用。

其中 String()、Number() 和 Boolean() 函数都可以用来对任意类型的数据进行显式类型转换。

另外 Object() 函数也可用于显式类型转换,但本文不再展开。

String

示例代码:

typeof String();    // "string" String();           // "" String('pp');       // "pp" String(123);        // "123" String(true);       // "true" String(false);      // "false" String(null);       // "null" String(undefined);  // "undefined" String([]);         // "" String({});         // "[object Object]"

小贴士 1

当我们使用 String() 函数来转换对象时,JavaScript 会先访问对象上的 toString() 函数,如果没有实现,则会顺着原型链向上查找。

举个栗子:执行 String({ toString() { return 'pp'; } }) 返回的结果是 "pp",并非 "[object Object]"。

所以 String() 函数并不能够用来判断一个值是否为对象(会翻车)。

小贴士 2

常用的判断对象的方式为 Object.prototype.toString({}) === '[object Object]'。

举个栗子:执行 Object.prototype.toString({ toString() { return 'pp'; } }) 返回的是 "[object Object]"。

Number

示例代码:

typeof Number();    // "number" Number();           // 0 Number('');         // 0 Number('pp');       // NaN Number(123);        // 123 Number(true);       // 1 Number(false);      // 0 Number(null);       // 0 Number(undefined);  // NaN Number([]);         // 0 Number({});         // NaN

小贴士

对于 Number() 函数来说,可能最实用的转换就是将 true 和 false 转换为 1 和 0 吧。

Boolean

示例代码:

typeof Boolean();   // "boolean" Boolean();          // false Boolean('');        // false Boolean('pp');      // true Boolean(0);         // false Boolean(1);         // true Boolean(null);      // false Boolean(undefined); // false Boolean([]);        // true Boolean({});        // true

小贴士

某些情况下,我们会在数据中使用 0 和 1 来表示真假状态,此时就可以使用 Boolean() 进行状态的判断。

BigInt

BigInt() 函数用于将整数转换为大整数。

该函数接受一个整数作为参数,传入参数若为浮点数或任何非数字类型数据都会报错。

示例代码:

BigInt(123);        // 123n BigInt(123n);       // 123n typeof 123n;        // "bigint" typeof BigInt(123); // "bigint"

BigInt & Number

需要注意的是,BigInt 和 Number 是不严格相等(宽松相等)的。

示例代码:

123n === 123; // false 123n == 123;  // true

Symbol

Symbol() 函数用于创建一个 symbol 类型的值。

该函数接受一个字符串作为描述符(参数),如果传入其他类型的值则会被转换为字符串(除了 undefined)。

注意,每一个 symbol 值都是独一无二的,即使它们的描述符都是一样的。

且 symbol 类型的数据只能通过 Symbol() 函数来创建。

示例代码:

// 后面的返回值是 Devtools 模拟出来的,并非实际值 Symbol('pp');                   // Symbol(pp) Symbol(123);                    // Symbol(123) Symbol(null);                   // Symbol(null) Symbol({});                     // Symbol([object Object])  // 类型 typeof Symbol('pp');            // "symbol" Symbol('pp') === Symbol('pp');  // false  // 描述符 Symbol('pp').description;       // "pp" Symbol(123).description;        // "123" Symbol({}).description;         // "[object Object]" Symbol().description;           // undefined Symbol(undefined).description;  // undefined

原始值不是对象 (Primitive not Object)

有意思的来了~

没有属性和方法 (No properties, no functions)

本文前面有提到:「原始值是一种没有任何方法的非对象数据。」

我们都知道对象(Object)上可以有属性和方法。

但是字符串不是对象,所以你不能给字符串增加属性。

做个小实验:

let a = 'chenpipi'; console.log(a.length);  // 8 // 尝试增加新的属性 a.name = '吴彦祖'; console.log(a.name);    // undefined // 尝试修改已有的属性 typeof a.slice;         // "function" a.slice = null; typeof a.slice;         // "function"

渣皮小剧场

此时一位头铁的小伙伴使用了反驳技能。

渣皮你别在这忽悠人了,我平时写 Bug 哦不写代码的时候明明可以调用到字符串、数字和布尔值上的方法!

比如下面这段代码,能够正常执行并得到符合预期的结果:

// 字符串 let s = 'chenpipi'; s.toUpperCase();      // "CHENPIPI" 'ChenPiPi'.slice(4);  // "PiPi" // 数字 let n = 123; n.toString();         // "123" (123.45).toFixed(2);  // "123.5" // 布尔值 let b = true; b.toString();         // "true" false.toString();     // "false"

无用小知识

有没有发现,数字的字面量后面不能直接调用函数?例如执行 123.toString() 会报 SyntaxError(语法错误)。

这是因为数字(浮点数)本身会用到小数点 .,而调用函数也需要用小数点,这时就出现了歧义(字符串和布尔值就没有这种烦恼)。

对于这种情况,我们可以使用括号 () 将数字包裹起来,如 (123).toString();或者使用两个连续的小数点 .. 来调用函数,如 123..toString()。

奇了怪了

那么既然字符串不是对象,那么为什么字符串会有属性和方法呢?

转念一想,数字就是数字,数字身上怎么会有方法呢?

这确实不符合逻辑,但是这又与实际相矛盾。

咋回事呢???

替身使者 (I can't translate this)

答案揭晓~

暗中操作

以字符串(string)为例,当我们在代码中读取字符串的属性或者方法时, JavaScript 会静默地执行下面的操作:

  1. 鸿蒙官方战略合作共建--HarmonyOS技术社区

  2. 将字符串通过 new String() 的方式来创建一个临时的包装对象实例;

  3. 通过创建的对象来执行我们的代码逻辑(读取属性或执行函数);

  4. 临时对象不再使用,可以被销毁。

如下面的栗子:

let a = 'chenpipi'; console.log(a);   // "chenpipi" // ------------------------------ let b1 = a.length; console.log(b1);  // 8 // 上面的代码相当于: let b2 = (new String(a)).length; console.log(b2);  // 8 // ------------------------------ let c1 = a.toUpperCase(); console.log(c1);  // "CHENPIPI" // 上面的代码相当于: let c2 = (new String(a)).toUpperCase(); console.log(c2);  // "CHENPIPI"

数字(number)和布尔值(boolean)同理,但数字通过 new Number() 来创建临时对象,而布尔值则通过 new Boolean() 来创建。

除了上面的例子,最有力的证明,就是他们的构造函数:

'chenpipi'.constructor === String;  // true (12345).constructor === Number;     // true true.constructor === Boolean;       // true

这一切都是 JavaScript 在暗中完成的,且过程中产生的临时对象都是一次性的(用完就丢)。

原来如此

芜湖,这么一来就说得通了!

这也就能解释为什么我们能够访问字符串上的属性和方法,却不能增加或修改属性。

那是因为我们实际操作的目标其实是 JavaScript 创建的临时对象,而并非字符串本身!

所以我们的增加或修改操作实际上是生效了的,只不过是在临时对象上生效了!

就像这样:

// 代码中: let a = 'chenpipi'; a.name = '吴彦祖'; console.log(a.name);  // undefined  // 相当于: let a = 'chenpipi'; (new String(a)).name = '吴彦祖'; console.log(a.name);  // undefined  // 相当于: let a = 'chenpipi'; let temp = new String(a); temp.name = '吴彦祖'; console.log(a.name);  // undefined

到此,关于"JavaScript原始值与包装对象介绍"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

对象 函数 类型 字符 原始 字符串 数字 包装 代码 属性 方法 布尔 数据 示例 实际 整数 面的 吴彦祖 实例 就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 做软件开发工作对胎儿锻炼脑力 公安网络安全管理岗位 网络安全治理综述 行业网络安全建设方案 南山小程序软件开发 宿州手机软件开发定制公司 松江区网络技术咨询创新服务 网络安全管理snmp 服务器暴躁八卦图 数据库技术与应用英语怎么说 网络安全工作调研会议 软件开发企业账务处理2021 田忌赛马翻译软件开发 高校后勤网络安全问题 步道乐跑服务器开小差修复要多久 服务器双网卡一个内网同时传输 小萌加油互联网科技有限公司 软件开发工作量天数除以22 服务器bios退出安全模式 软件开发公司形象广告语 小学举办网络安全活动 服务器系统一般装什么版本 手机版远古服务器 移动加权平均法数据库技术 网络安全在日本有哪些好大学 大专软件开发电脑配置推荐 网络技术课程是什么 天龙八部3精通数据库 云南省网络安全信息办公室 sap数据库结构
0