面试官随手出的一道题,大有玄妙--Javascript知识点:包装类

127 阅读5分钟

前言

在JavaScript中,虽然没有明确像Java那样的包装类的概念,但基本数据类型在某些情境下会被自动“包装”成对象,以便能够调用一些方法或属性。JavaScript中的原始数据类型(Number, String, Boolean)在需要时会临时地被封装成对象,这个过程是自动且透明的。

正文

要了解包装类,首先我们需要知道JavaScript的几个基础概念

1.对象

你的想象的对象是什么样的?

章若楠?

image.png

走错片场了!

对象:在JavaScript中,对象(Object)是一种复合数据类型,用于存储键值对的集合。对象允许将数据(属性)和行为(方法)组织在一起,形成更加复杂的数据结构。

而在JavaScript中,一切皆为对象!

JavaScript中除了基本类型(undefined、null、boolean、number、string、symbol、bigint)外,几乎所有的值都是对象,包括函数也是一种特殊的对象。即使是基本类型,通过包装类机制也可以被当作对象来处理。

2.如何创建对象

没有对象?没有对象我们就找一个......呸,new一个!

第一种,也是最简单的方法,创建对象字面量(注意这个,后面会有提到)

var obj = {}

第二种,有点多余的写法,不推荐用。

var obj2 = new Object()

第三种,我们可以先写一个构造方法例如:

function Car() {

    this.name = 'su7'
    this.height = 1400
    this.long = 5000
    this.weight = 1000
}

接着再new一个对象

let car1 = new Car()

这么多创建对象的方式,那你的对象呢?

我们现在来正式讲一下包装类

我们先来看一个例子:

var num = 123
num.a = 'aaa'
console.log(num.a);

看看它的运行结果是怎么样的

image.png

为什么是undefined呢?

对一个对象添加属性和方法正是以上面的形式,但是我们对num是以字面量的形式创建的,像Number String这样的我们如果以字面量形式定义它为原始值,它并不能以对象的形式存在

原始值是不能拥有属性和方法的,属性和方法只有对象才能拥有

我们再来看一个例子:

var num =new Number(123)
console.log(num*2);
num.a = 'aaa'
console.log(num.a);

代码中,创建了一个数字对象,也就是以对象的形式创建了一个原始值

那我们到底是创造了一个对象还是原始值呢?

如果是对象,我们打印num*2的时候却又可以输出正确的值,对象是无法做运算的

如果是原始值,它又添加了属性

事情好像开始变得奇怪了起来,到底是怎么回事呢‘

我们来到浏览器上来看一下

image.png

我们可以发现它就是一个对象,它也是一个数字,它能当成对象来用,也能当成数字来用。

当你把它当对象来用,它就是一个对象,当你把它当成数字用的时候,它就是一个数字。

这样对象是一个特殊的对象,叫做数字对象。

我们知道这样一个特殊的对象存在,我们再来看一下:

var str = 'abcd'   
console.log(str.length);

既然我们说原始值不能有属性和对象,那么这个字符串的长度的方法是怎么来的呢?

敲黑板!

举个例子:

var num =4 
num.len =3 
console.log(num.len)

在执行第一行代码的时候,实际上在v8引擎的思考中,它就是new了一个对象new Number(4)

而且在执行第二行代码的时候,它也确实生成了new Number(4).len =3这样的类型

但是,v8引擎会回过头来发现,你定义的是一个字面量原始值,并不是一个对象,就不能把它当成对象来用。

所以v8引擎会执行一个语句delete num.len

到这里,我们就差不多了解什么是包装类

当尝试访问原始类型值的一个属性或方法时,JavaScript会临时创建一个对应包装类型的对象,然后访问该对象的属性或方法,之后这个临时对象就会被销毁,像这样的原始值对象,就是包装类。

我们再回过头来看这个str.length是原始类型对象上附带的属性,而我们不能往原始类型对象上添加属性。

而如何判断这个值是否是一个原始值,v8引擎只用了一句valueOf()就可以识别出来。

如果valueOf()后有值,那么它就是一个原始类型,如果valueOf()没有值,它就是一个对象

有值,我们就把它后面添加的属性和方法都delete掉,没有值,我们就保留,这就是包装类的一个十分巧妙的特性。

也是JavaScript的魅力之一:

万物皆为对象!

我们再看看面试官出的题目

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

请问这个输出结果是什么?

相信答案已经很明朗了,test是一串字符串,是包装类,无法往包装类里添加方法和属性,所以,答案是 image.png

求点赞评论收藏,有问题随时私信博主!