JavaScript 你不知道的基本包装类型

JavaScript 你不知道的基本包装类型

声明:本文的大部分内容参考自《JavaScript 高级程序设计(第三版)》(中文版 P.118),中间夹杂一些自己阅读这部分内容时的思路。

JavaScript 中共有 6 种基本数据类型:UndefinedNullBooleanNumberStringSymbol (new in ES 6)

举例子入门

基本数据类型的值不是对象,因而从逻辑上讲它们不应该有方法或者属性,然而事实并不是我们所想的那样,看法宝:

var str = "hello world";
str.length;              // 11
str.toUpperCase();       // HELLO WORLD

你对上面的现象有疑问吗?没有的话,可以关掉这个页面了。

引入基本包装类型

为了便于操作基本数据类型的值,JavaScript 中的原始数据类型的值会在后台隐式地被包装为对象,从而引出了基本包装类型(primitive wrapper type)这个概念。

【书中原话】每当读取一个基本类型的值的时候,后台就创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。

这也是为什么书中会提到这句话,ECMAScript 还提供了3个特殊的引用类型:BooleanNumberString。哦,不对了,现在不是又出现了一种新的数据类型吗?所以,这句话应该改为:ECMAScript 还提供了4个特殊的引用类型:BooleanNumberStringSymbol

除了 null 和 undefined,所有的原始值都有等价的、由对象包装原始值的形式表达,取而代之,nullundefined 常被当作一个全局对象的全局属性来使用。

window.null;          // undefined
window.undefined;     // undefined
null == undefined;    // true
null === undefined;   // false

继续刚开始的那个例子

为了方便,就把前面的代码直接挪过来了。

var str = "hello world";
str.length;              // 11
str.toUpperCase();       // HELLO WORLD

我们看到的代码是上面的样子,其实后台会自动完成下列的处理:

  • 执行到第二行时:

    • 创建 String 类型的一个实例;

    • 在实例上调用指定的属性

    • 销毁这个实例;

  • 执行到第三行时:

    • 创建 String 类型的一个实例;

    • 在实例上调用指定的方法

    • 销毁这个实例;

可以将上面的步骤想象成下列 ECMAScript 代码:

// 执行到第二行时
var str = new String("hello world");
str.length;
str = null;

// 执行到第三行时
var str = new String("hello world");
str.toUpperCase();
str = null;

经过此番处理,基本的字符串值就变得跟对象一样啦。而且,上面的步骤同样适用于 Boolean 类型的 Number 类型对应的布尔值和数字值。

嘿嘿,啰嗦了这么多,搞懂了吗?

引用类型与基本包装类型的区别

引用类型与基本包装类型的主要区别就是对象的生存期。

使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前,会一直保存在堆内存中。而后台自动创建的基本包装类型的对象,则只存在一行代码的执行瞬间,然后立即被销毁。这意味着我们不能为基本类型的值添加属性和方法。

看了上面的原理,再来看例子:

var str = "some text";
str.color = "red";
console.log(str.color);   // undefined

在此,第二行表面上看是为 str 添加了 color 属性,但是仔细回想上面的后台执行的那 3 个步骤,会发现,第二行创建的 String 对象在添加了 color 属性后,被销毁了。执行到第三行时,第三行代码又创建了自己的 String 对象,然而这个对象没有 color 属性。一切都显得那么清晰。

为了与上面的例子形成对比,我们显式地创建基本包装类型的对象,代码如下:

var str = new String("some text");
str.color = "red";
console.log(str.color);     // red

书中有警告:除非绝对必要,否则不要显式地创建基本包装类型的对象,因为这种做法很容易让人分不清自己是在处理基本类型还是引用类型的值。

var value = "25";

var number = Number(value);   // 转型函数
console.log(number);          // 25

var obj = new Number(value);  // 构造函数
console.log(typeof obj);      // object 
console.log(obj);             // Number {[[PrimitiveValue]]: 25}

Boolean 引用类型

书中很严肃地说:理解基本类型的布尔值与 Boolean 对象之间的区别非常重要------当然,我们的建议是永远不要使用 Boolean 对象

funny

吐槽一下,segmentfault 好像不让上传本地的无聊表情包,所以只好外链过来了。喔草,我刚刚说了什么。。。

Number 引用类型

【MDN】传送门---Number

var num = 1.2345678;

num.toFixed(2);        // 1.23
num.toPrecision(2);    // 1.2
num.toExponential(2);  // 1.23e+0

String 引用类型

【MDN】传送门---String

这个家伙的方法就很多了。

  • charAt()

  • concat()

  • slice()

  • indexOf()

  • trim()

  • toUpperCase()

  • toLowerCase()

  • match()

  • search()

  • replace()

  • .........

自己进门里面探索去吧!

Symbol 引用类型 (ES 6)

【MDN】传送门---Symbol

额,这个还没怎么用过呢。但是这里还是有一点需要注意下:

var sym = new Symbol();   // TypeError: Symbol is not a constructor

为什么会这样呢?这是因为围绕原始数据类型创建一个显式包装器对象从 ECMAScript 6 开始不再被支持。 然而,现有的原始包装器对象,如 new Booleannew String 以及 new Number 因为遗留原因仍可被创建。

好了,就这样结束吧!


percy507的编程之路
自2016年加入社区后,陆陆续续发布过一些文章,后面也自己折腾过个人博客(hexo+github)。但是自2018年...

主修前端,

962 声望
54 粉丝
0 条评论
推荐阅读
使用vite搭个中后台系统的脚手架
搭个中后台系统的脚手架仓库地址 [链接]搭建脚手架目的学习 vite、recoil 等新技术封装项目中常用的较复杂的组件学习一定的前端架构能力构建命令npm 与 yarn 对新版 husky(v7.0.1+)的配置方式不太相同,我们这...

percy5072阅读 3.2k

封面图
正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青56阅读 8.4k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy48阅读 6.9k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木75阅读 7k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs42阅读 6.8k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木45阅读 8.5k评论 6

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木35阅读 6.6k评论 10

主修前端,

962 声望
54 粉丝
宣传栏