# JavaScript 三大包装类 Number、String、Boolean

TIP

为了方便操作原始值,ECMAScript 提供了NumberStringBoolean这三个特殊的构造函数

他们的主要作用就是把基本数据类型 包装 成一个 “对象” 版本的基本类型值,所以这三个类又称为 包装类

包装类 说明
Number 将数字包装成一个数字对象
String 将字符串包装成一个字符对象
Boolean 将布尔值包装成一个布尔对象
// Number 类
var n = new Number(3);
console.log(n); // Number {3}
console.log(typeof n); // object
console.log(n + 4); // 7

// String 类
var str = new String("abcd");
console.log(str); // String {'abcd'}
console.log(typeof str); // object
console.log(str + "123"); // abcd123

// Boolean 类
var b = new Boolean(true);
console.log(b); // Boolean {true}
console.log(typeof b);
console.log(true + 1); // 2

# 一、包装类核心基础

TIP

  • 包装类的主要目的:是让基本类型值可以从它们的构造函数的 prototype 上获得方法。
  • 每当用到某个原始值的方法或属性时,后台都会创建一个相应的原始包装类型的对象,从而暴露出操作原始值的各种方法

我们来分析下,下面代码的执行流程

var str1 = "我就是我,不一样的小花朵";
var str2 = str1.charAt(2); // 是
  • 上面代码中 str1 是一个原始值,原始值不是一对象,因此逻辑上不能调用方法。但实际上按预期输出了结果。为什么呢 ?
  • 实际上代码执行到str1.charAt(2)时,JS 后台进行了很多处理

具体处理步骤如下:

  • 创建一个 String 类型的实例
str = new String(str1); // 创建对应String类型的实例
  • 调用实例上的特定方法,将返回的结果赋值给到 str2
str2 = str.charAt(2); // 完成赋值操作
  • 销毁创建出来的实例
str = null; // 销毁创建的实例

# 1、包装类的生命周期

TIP

  • new 关键字创建的原始值包装对象,只有在当前作用域被销毁时才销毁
  • 自动创建的原始值包装对象,只存在于访问它的那一行代码执行期间。执行完就自动销毁
var str1 = "我就是我,不一样的小花朵";
str1.name = "张三";
console.log(str1.name); // undefined
console.log(typeof str1); // string

var str2 = new String("我就是我");
str2.name = "清心";
console.log(str2.name); // 清心
console.log(typeof str2); // object

分析 str1 变量

  • 当代码执行到str1.name="张三"时,str1 确实被包装成了对象,然后在对象上添加了 name 属性,但执行完,被包装成的对象就销毁了
  • 当执行到str1.name时,str1 又创建了一个新的 String 对象,但是这个对象已经不是前面的那个对象,他身上没有 name 属性,访问对象身上不存在的属性不会报错,返回值为undefined

分析 str2 变量

  • 执行var str2 = new String("我就是我");时,相当于创建了一个包装对象,然后把这个包装对象赋值级到 str2
  • 当执行到str2.name = "清心";时,相当于给对象添加 name 属性
  • 当执行到str2.name时,相当于读到对象身上的属性,返回结果为清心

# 2、原始值包装对象 - 转为布尔值都是 true

TIP

直接调用 Boolean 函数,可以将其它类型转换为对应的 boolean 值

// 数字
console.log(Boolean(0)); // false
var n1 = new Number(0);
console.log(Boolean(n1)); // true
console.log(n1); // Number {0}

// 布尔值
var flag = new Boolean(false);
console.log(Boolean(false)); // false
console.log(Boolean(flag)); // true
console.log(flag); // Boolean {false}

// 字符串
var str = new String("");
console.log(Boolean(""));
console.log(Boolean(str));
console.log(str);

# 3、区分直接调用包装类与 new 调用

TIP

  • 直接调用包装类函数,主要目的是实现数据类型的转换
  • 使用 new 调用包装类,是为了把基本数据类型转换为对象类型
var value = "20";
var number = Number(value);
console.log(number); // 20
console.log(typeof number); // number

var obj = new Number(value);
console.log(obj); // Number {20}
console.log(typeof obj); // object

接下来我们学习这些包装类身上的相关属性和方法

# 二、Number 包装类

TIP

Number 类有很多方法和属性,我们这里挑出最常用的给大家讲解

点击,更多详细内容参考 MDN 官方 (opens new window)

以下是常见的 Number 的静态属性,只需要了解即可

静态属性 描述
Number.MAX_SAFE_INTEGER 表示在 JavaScript 中最大的安全整数2^53 - 1
Number.MIN_SAFE_INTEGER 代表在 JavaScript 中最小的安全整数 -(2^53 - 1)
Number.MAX_VALUE JavaScript 里所能表示的最大数值
大于 MAX_VALUE 的值代表 "Infinity"
Number.MIN_VALUE 表示在 JavaScript 中所能表示的最小的正值
小于 MIN_VALUE ("underflow values") 的值将会转换为 0

以下是常用的 Number 原型上的方法,之些方法我们之前都学习过,列出来用于复习

实例方法(原型方法) 描述
toFixed 返回结果后的小数部分保留指定小数位数,返回结果为一个字符串
保留小数位时,会采用四舍五入
如果小数位不足,则用 0 来补充
如果参数为空,则表示不保留小数位
toString toString()用来将数值类型转换为字符串类型
toString()可以接受一个参数,用来将数字转换成对应进制的字符串
valueOf valueOf 方法返回被 Number 对象包装的原始值

# 1、Number.MAX_SAFE_INTEGER 属性

TIP

  • 是一个值为 9007199254740991 (即2^53-1)的常量。
  • 表示在 JavaScript 中最大的安全整数(maxinum safe integer)(2^53 - 1
  • 所谓的安全,是指能够准确的区分两个不相同的值
var n = Math.pow(2, 53) - 1;
console.log(n); // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

// 安全系数  以下得到结果为true,显然是不合理的
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true

# 2、Number.MIN_SAFE_INTEGER 属性

TIP

  • 是一个值为 -9007199254740991的常量,即 -(2^53 -1)
  • 表示在在 JavaScript 中最小的安全整数 -(2^53 - 1)
  • 所谓的安全,是指能够准确的区分两个不相同的值
var n = -(Math.pow(2, 53) - 1);
console.log(n); // -9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991

// 安全系数  以下得到结果为true,显然是不合理的
console.log(Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGER - 2); // true

# 3、Number.MAX_VALUE 与 Number.MIN_VALUE 属性

TIP

  • Number.MAX_VALUE表示 JavaScript 里所能表示的最大数值
  • Number.MIN_VALUE 表示在 JavaScript 中所能表示的最小的正值
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324

# 4、toFixed 方法

TIP

  • 返回结果后的小数部分保留指定小数位数,返回结果为一个字符串
  • 如果参数为空,则表示不保留小数位
  • 保留小数位时,会采用四舍五入
  • 如果小数位不足,则用 0 来补充
var n = 1.447;
console.log(n.toFixed()); // 1
console.log(n.toFixed(1)); // 1.4
console.log(n.toFixed(2)); // 1.45
console.log(n.toFixed(5)); // 1.44700
console.log(typeof n.toFixed()); // string

# 5、toString 方法

TIP

  • Number 类重写了原型上的 toString 方法
  • toString()用来将数值类型转换为字符串类型
  • toString()可以接受一个参数,用来将数字转换成对应进制的字符串
var n = 16;
console.log(n.toString()); // 16
console.log(typeof n.toString()); // string
console.log(n.toString(2)); // 10000
console.log(n.toString(8)); // 20
console.log(n.toString(10)); // 16
console.log(n.toString(16)); // 10

# 6、valueOf 方法

TIP

  • Number 类重写了原型上的 valueOf 方法
  • valueOf 方法返回被 Number 对象包装的原始值

该方法通常是由 JavaScript 引擎在内部隐式调用的,而不是由用户在代码中显式调用的

var n = 16;
var obj = new Number(n);
console.log(obj); // Number {16}
console.log(obj.valueOf()); // 16
console.log(obj + 3); // 19 内部自动调用了valueOf方法

# 三、Boolean 包装类

以下是 Boolean 包装类原型上的方法

实例方法(原型方法) 描述
toString 方法返回表示指定的布尔对象的字符串
valueOf 返回一个原始值truefalse

# 1、toString 方法

TIP

  • Boolean 类重写了原型上的 toString 方法
  • 方法返回表示指定的布尔对象的字符串
  • 当一个 Boolean对象作为文本值或进行字符串连接时,JavaScript 会自动调用其 toString 方法
console.log(true.toString()); // 'true'
console.log(typeof true.toString()); // string
console.log(false.toString()); // 'false'
console.log(true + "abc"); // trueabc 内部自动调用了toString()方法

# 2、valueOf

返回原始值truefalse

var flag = new Boolean("12");
console.log(flag); // Boolean {true}
console.log(flag.valueOf()); // true

var flag2 = new Boolean(0);
console.log(flag2); // Boolean {false}
console.log(flag2.valueOf()); // false

建议永远不要使用 new Boolean() 来包装一个布尔值,这里只当做了解

# 四、String 包装类

实例(原型)方法 描述
charAt() 返回字符串中指下标的字符
concat() 将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回
indexOf 返回给定的字符串在整个字符串中第一次出现的索现
slice 方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。
substring 返回字符串中指定开始索引到结束索引之间的字符串,包含起始索引,不包含结束索引
trim 清除字符串两端的空格,返回一个新的字符串
trimEnd 方法会删除字符串末尾的空白字符。trimRight() 是这个方法的别名
trimStart 方法会删除字符串开头的空白字符。trimLeft() 是此方法的别名
toUpperCase() 将字符串中字母转换为大写
toLowerCase() 将字符串中字母转换为小写
valueOf 返回 String 对象的原始值

温馨提示

这些字符串方法(splitmatchsearchreplace)涉及到正则表达式的应用,则放在正则表达式那一章节来学

# 1、charAt

TIP

  • 返回字符串中指定下标的字符
str.charAt(index);
  • index 值介于 0 ~ 字符串长度-1 之间的整数,如过值超出这个范围,返回空字符串
  • 如果没有传入参数,则默认返回下标为 0 的字符
var str = "我就是我,不一样的小花朵";
console.log(str.charAt()); // 我
console.log(str.charAt(str.length - 1)); // 朵
console.log(str.charAt(str.length)); // 超出范围 返回空字符串
console.log(str.charAt(-1)); // 超出范围 返回空字符串

# 2、concat

TIP

  • 将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。
  • 如果传入的参数为非字符串,会先转换成字符串,然后再拼接
  • concat 方法,并不影响原字符串

MDN 上明确强调:出于性能考虑,强烈建议使用 ++= 来代替 concat() 方法拼接字符串

str.concat(str2, [, ...strN]); // [] 里面表示可选,即concat的中的参数 >= 1个
var str = "abc";
console.log(str.concat("c")); // abcc
console.log(str.concat("c", 4, 5)); // abcc45
console.log(str.concat(["d", "e", "f"])); // abcd,e,f
console.log(str.concat(true)); // abctrue
console.log(str.concat(null)); // abcnull
console.log(str.concat([])); // abc
console.log(str.concat({})); // abc[object Object]
console.log(str.concat({ a: 1, b: 2 })); // abc[object Object]

# 3、indexOf

TIP

  • 返回指定字符串在大于或等于position位置的第一次出现的索引,如果没有找到则返回 -1
  • searchString 要搜索的子字符串
  • position 从指定位置开始往后查询
indexOf(searchString);
indexOf(searchString, position);
  • 如果没有传第二个参数,则默认从 0 的位置开始查找
  • 给定了第二个参数,会从当前位置开始往后查找,包括当前位置
var str = "hello world";
console.log(str.indexOf("o")); // 4
console.log(str.indexOf("o", 7)); // 7
console.log(str.indexOf("o", 8)); // -1
  • 如果 position 大于字符串长度,则搜索不到对应字符串,返回结果为 -1
  • 如果 position 小于 0,则当成 0 来处理,从第 0 的位置往后查询

数组中的 indexOf 方法,如果第二个数是负数,则表示从后往前找

var str = "hello world";
console.log(str.indexOf("o", 11)); // -1
console.log(str.indexOf("o", -4)); // 4
  • indexOf 查询内容时,是严格区分大小写的,数组中的 indexOf 方法也是一样的
var str = "hello world";
console.log(str.indexOf("W")); // -1
console.log(str.indexOf("w")); // 6

空字符串搜索时会产生以下奇怪的结果,所以在查询时如果查询内容有可能为空,则需要提前判断

  • position 未传,返回结颗粒 0,如 position < 字符串长度,返回结果为 position 值
  • position >= 字符串长度,返回结果为字符串的长度
// 以下代码来自MDN
"hello world".indexOf(""); // 返回 0
"hello world".indexOf("", 0); // 返回 0
"hello world".indexOf("", 3); // 返回 3
"hello world".indexOf("", 8); // 返回 8

"hello world".indexOf("", 11); // 返回 11
"hello world".indexOf("", 13); // 返回 11
"hello world".indexOf("", 22); // 返回 11

案例应用: 统计某个字母或单词在字符串中出现的次数

String.prototype.count = function (searchString, position) {
  var n = 0; // 统计字符串出现的次数
  if (position === undefined) position = 0; // 如果没有赋值,默认为0
  if (typeof position !== "number") {
    // 如果不是数字类型,则抛出错误
    throw new TypeError("position只能是数字类型");
  }
  // 从当前位置往后查找,并将查询的位置结果返回
  position = this.indexOf(searchString, position);
  while (position !== -1) {
    n++;
    position = this.indexOf(searchString, position + 1);
  }
  return n;
};

var str = "on test my love on top bottom test";
console.log(str.count("on"));
console.log(str.count("o", 2));
console.log(str.count("test", -2));

# 4、slice

TIP

  • 方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串
  • 其用法和数组的 slice 方法一样
str.slice(beginIndex[, endIndex])
  • beginIndex为查询的起始索引,默认为 0
  • endIndex为结束索引,可选参数,默认不写,表示从结束位置提取到整个字符串的尾部。
  • 如果beginIndexendIndex为负数,表示从后往前数,找到对应位置,再从开始位置向右查询到结束位置。
  • 从后往前数,下标从-1 开始,同时查询字符串包含 beginIndex,但不包换endIndex
var str = "abcdefc";
console.log(str.slice(2, 5)); // cde
console.log(str.slice(2, -2)); // cde
console.log(str.slice(-5, -2)); // cde
console.log(str.slice(-3)); // efc

# 5、substring

TIP

返回字符串中指定开始索引到结束索引之间的字符串,包含起始索引,不包含结束索引

str.substring(startIndex[, endIndex])
  • startIndex开始索引,如果小于 0 或为 NaN,则当成 0 处理,大于字符串长度,则当成字符串长度处理
  • endIndex 结束索引,如果小于 0 或为 NaN,则当成 0 处理,大于字符串长度,则当成字符串长度处理
  • 如果 startIndex > endIndex ,则执行效果像两个参数调换一样
var str = "abcdefc";
console.log(str.substring(2)); // cdefc
console.log(str.substring(-2)); // abcdefc
console.log(str.substring(5, 2)); //cde
console.log(str.substring(2, -3)); // ab
console.log(str.substring(2, 5)); //cde
console.log(str.substring(-2, -3)); //""

# 6、trim、trimEnd、trimStart

TIP

  • trim:清除字符串两端的空格,返回一个新的字符串
  • trimEnd: 方法会删除字符串末尾的空白字符,trimRight() 是这个方法的别名
  • trimStart:方法会删除字符串开头的空白字符,trimLeft() 是此方法的别名

这里的空格是指:所有的空白字符(空格、tab、不换行空格等)以及所有行终止符字符(如 LF、CR 等)

var str = "   abc   ";
var newstr = str.trim();
console.log(str.trim()); // "abc"
console.log(str.trim().length); // 3

console.log(str.trimStart()); // "abc   "
console.log(str.trimStart().length); // 6

console.log(str.trimEnd()); // "   abc"
console.log(str.trimEnd().length); // 6

# 7、toUpperCase 与 toLowerCase

TIP

  • toLowerCase:将字符串中字母全部转换为小写
  • toUpperCase : 将字符串中字母全部转换为大写
var str = "I love You 是我爱你";
console.log(str.toUpperCase());
console.log(str.toLowerCase());
  • 以下方法可实现将 true、false 这些非字符串值转换全大写
String.prototype.toUpperCase.call(true);
String.prototype.toUpperCase.call(false);
  • 以下代码会抛出类型错误
String.prototype.toUpperCase.call(null);
String.prototype.toUpperCase.call(undefined);

image-20221208004420970

# 8、valueOf

TIP

valueOf() 返回 String 对象的原始值

var obj = new String("wang");
console.log(obj); // String {'wang'}
console.log(obj.valueOf()); // wang

// 字符串拼接时,会自动调用valueOf方法,获取原始值来拼接
console.log(obj + "abc");

# 五、重点总结

TIP

为什么要有三大包装类 ?

  • 包装类的主要目的:是让基本类型值可以从它们的构造函数的 prototype 上获得方法。

理解包装类的生命周期 ?

  • 重点掌握 toFixed、charAt、concat、indexOf、slice、substring、trim、trimEnd、trimStart、toUpperCase、toLowerCase 用法
上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X