Js基本包装类型(含原理)

前言

错误理解:

之前对Js基本包装类型的理解是,当我们创建了一个基本类型的变量时,Js会自动为我们将其包装(转换)成基本包装类型的实例,所以我们才能直接调用它的属性的方法。

// 因为基本包装类型的存在,下边代码可以执行,我们可以直接对基本类型调用方法
let str = 'hello'
substr = str.substring(2)

其实关于str到底是什么类型,我也没有太在意过,今天偶尔的一个测试却让我发现事情没有那么简单。

可以看到,str不是一个实例对象,而是一个基本类型变量

var str = "string"
console.log(str instanceof String) //false
console.log(typeof str) //string

所以这也就触发了我今天对基本包装类型的探究,总结如下:

基本包装类型

为了便于操作基本类型值,ECMAScript提供了一些特殊的引用类型:比如Boolean、Number和String等。这些类型与其他引用类型相似,但具有与各自的基本类型相应的特殊行为

除了 nullundefined之外,所有基本类型都有其对应的包装对象:

  • String
  • Number
  • BigInt
  • Boolean
  • Symbol

按道理基本数据类型是没有属性和方法的,对象才有属性和方法。

但下面代码却可以执行:

// 下面代码有什么问题?
let str = 'hello';
substr = str.substring(2);

原理

实际上,每当我们对一个保存了基本类型值(比如number,string和boolean)的变量调用方法(或者访问属性)的时候,后台就会创建一个对应的基本包装类型的对象,对他们调用我们所指定的方法来得到我们想要的数据。

具体过程如下:

  1. 根据对象保存的基本类型值,创建对应类型的实例对象

  2. 在这个实例上调用我们所指定的方法

  3. 立即销毁这个实例

上边声明了str变量,并对其调用substring方法的代码等同于下边代码:

let str = 'hello';
// 1. 生成临时变量,保存基本包装类型实例
var temp = new String(str);
// 2. 对实例调用方法
substr = temp.substring();
// 3. 销毁临时变量
temp = null;

引用类型与基本包装类型的主要区别就是对象的生存期,使用new创建的引用类型实例当执行流离开当前作用域之前,都一直保存在内存中,而自动创建的基本包装类型的对象,则只存在于一行代码执行的瞬间,然后就被销毁。这就意味着我们不能给基本包装类型添加属性和方法。

let s = 'JavaScript';
s.language = 'ECMAScript';
console.log(s.language); // undefined

上边代码试图给s添加一个language属性,但是当我们再次输出该属性的时候却得到undefined。

这是因为s.language = 'ECMAScript';这句代码执行时,Js内部创建了一个String类型的实例,并在这个实例身上添加了language属性,但是这行代码执行完毕之后,这个实例马上就被销毁了,当我们执行console.log(s.language);这句代码时,又重新创建了一个实例对象,这个实例对象和上一句代码所创建的实例对象不是一个,自然也没有language属性。

一般来说,不推荐直接声明基本包装类型对象。

//不推荐
let n = new Number(10);
let s = new String('JS');
let b = new Boolean(false);

我们只需要知道基本包装类型对象身上(准确的来说是他的原型身上)有哪些方法,我们直接声明基本类型变量调用即可。

总结

  • 基本包装类型的实例会在我们调用一些基本类型变量方法(或属性)的时候被自动创建
  • 我们对基本类型变量调用的方法(或访问属性),Js底层会对基本包装类型实例操作
  • 基本包装类型的实例只会存在于一行代码执行的一瞬间,然后就会被立即销毁
  • 不推荐手动创建基本包装类型实例

猜你喜欢

转载自blog.csdn.net/weixin_42619772/article/details/122510569