前言
在学习js的过程中我陆陆续续了解到一些在js中比较'奇怪'的知识点,本文中就要提到的包装类就是一个让人摸不着头脑的地方。
js中的数据类型
讲到包装类之前就必须要先了解一下js中的基本类型:
1. 基本数据类型
JavaScript 中的基本数据类型包括以下几种:
a. 数字(Number): 用于表示数值,包括整数和浮点数。例如:let num = 10;
b. 字符串(String): 用于表示文本数据,可以使用单引号或双引号括起来。例如:let str = 'Hello';
c. 布尔值(Boolean): 只有两个值,true 和 false,用于表示逻辑值。例如:let isTrue = true;
d. undefined: 表示未定义或未初始化的值,当变量声明但未赋值时,默认为 undefined。例如:let x;
e. null: 表示空值或不存在的对象,常用于表示空对象或清空对象。例如:let obj = null;
2. 对象类型
JavaScript 中的对象类型包括以下几种:
a. 对象(Object): 对象是一种复合值,用于存储多个键值对的集合,键是字符串,值可以是任意类型的数据。例如:
css
javascriptCopy code
let person = {
name: 'Alice',
age: 30
};
b. 数组(Array): 数组是一种有序集合,用于存储多个值,每个值都有一个数字索引,索引从 0 开始。例如:
ini
javascriptCopy code
let numbers = [1, 2, 3, 4, 5];
c. 函数(Function): 函数是 JavaScript 中的一等公民,可以作为变量进行传递和赋值,也可以作为对象的属性和数组的元素。例如:
javascript
javascriptCopy code
function greet(name) {
console.log('Hello, ' + name + '!');
}
js中包装类
想必大家都了解,js中对象是可以添加属性和方法的,例如:
javascript
let obj = {
name: '丁总',
age: 18,
getname: function(){
console.log(name)
}
}
console.log(obj['name']) //输出的是 丁总
// obj.girlFriend = '翠花'
let girl = 'girlFriend'
obj[girl] = '小红' //给实例对象obj赋予'girlfriend的属性为' 小红
delete obj[girl] //删除实例对象中的'girlfriend'属性
console.log(obj); // 输出为 {name:'丁总',age:18}
console.log(obj.getname()) //输出为丁总
那如果给你一段下面的代码,你可以看出输出的结果是多少吗?
ini
var num = 123
num.abc = 'hello'
console.log(num.abc);
想必大家都和我一样刚开始看到的时候都觉的可能是hello
,但是仔细一看就觉得不对劲,这不是基本类型的,它怎么可以含有属性呢?那答案就是运行错误咯。 前一句话是对的,但是后一句话就不对了,它可以运行,但是答案是undefined。为什么呢?
dart
var num = new Number(123)
num.abc = 'hello'
console.log(num.abc); // 输出为'hello'
console.log(num * 2); // 参与运算时会变成数字,输出为'246'
明明num
都是等于123
为什么运行出来的结果差距这么大?
这个时候就不得不提到构建函数了,当new Number(123)
时,实际上返回给num的是一个对象,new
的过程有三步:
kotlin
1. 隐式创建一个this = {}
2. 执行 函数中的 this.xxx = xxx
3. 隐式的返回this
var num = new Number(123)
就相当于是
function Number(){
var this = {
xxx:xxx
}
return this
}
这样一来var num = new Number(123)
返回的是一个对象,所以就可以给num
添加属性。
包装类的介绍
看完前面的内容,我不由得好奇为什么String
中不是有一些方法吗?例如:indexOf()
、join()
、split()
等。这些都是因为包装类的的作用。
JavaScript 中的包装类主要有三种:String、Number 和 Boolean。它们的作用主要有以下几点:
- 提供了额外的方法和属性: 包装类为基本数据类型提供了一系列的方法和属性,使得基本数据类型拥有了更多的功能。例如,String 类提供了
toUpperCase()
、substring()
等方法,Number 类提供了toFixed()
、toPrecision()
等方法。 - 允许直接调用原型方法: 通过包装类对象,我们可以直接调用原型方法,而无需手动将基本数据类型转换为对象。例如,我们可以直接调用字符串的原型方法,如
String.prototype.toUpperCase()
,而不需要先将基本数据类型转换为对象。 - 提供了类型转换的方式: 包装类对象可以通过调用一些方法,将基本数据类型转换为相应的字符串、数字或布尔值。例如,可以通过
String()
函数将其他数据类型转换为字符串类型,通过Number()
函数将其他数据类型转换为数字类型,通过Boolean()
函数将其他数据类型转换为布尔类型。
包装类的运行原理
css
var a = '123'
console.log(a.length)
当执行 console.log(a.length)
时,JavaScript 引擎会按照以下步骤执行:
- 首先,它会检查变量
a
是否已经被声明和赋值。在这个例子中,变量a
已经被声明并赋值为字符串"123"
。 - 然后,它会调用
a
的length
属性。因为a
是一个字符串,而字符串是基本数据类型,没有自己的属性和方法。所以 JavaScript 引擎会隐式地将a
转换为一个 String 包装类对象。 - 接下来,JavaScript 引擎会访问 String 对象的
length
属性,这个属性表示字符串的长度。 - 最后,JavaScript 引擎会将这个长度返回,并通过
console.log()
打印出来。
总之,虽然字符串是 JavaScript 中的基本数据类型,但是在访问属性或方法时,JavaScript 引擎会将其隐式转换为包装类对象,然后再进行操作。这个过程称为自动装箱。
结语:一个有用的知识
想必大家都还没忘记这一段代码:
ini
var num = 123
num.abc = 'hello'
console.log(num.abc); //undefined
这个输出结果的原因是:当代码执行到num.abc
的时候,会将num.abc
变成new Number(123).abc = 'hello'
,后面由于基本类型是不能拥有属性和方法的,所以立马执行下一步delete
将new Number(123).abc = 'hello'
这一段的结果删掉,于是乎代码运行到最后一句的时候就成了console.log('new Number(123).abc')
得到的结果就是undefined。
这一个知识点比较重要,在一些面试的时候,面试官都可能会提到。当然面试时可能不是这样简单的代码,可能会出现一些变化,那时候就要看自己的掌握程度了。