前言:
在本文中将主要对Symbol和BigInt以及注意事项多做讲解,在JavaScript中,有以下原始类型和引用类型:
一、原始类型与引用类型
-
原始类型(Primitive Types):
- 字符串(String):例如:"Hello World"
- 数字(Number):例如:42, 3.14
- 布尔值(Boolean):例如:true, false
- undefined:表示未定义的值
- null:表示空值
- Symbol:表示唯一的、不可变的值
- BigInt:用于表示任意精度的整数,例如:123n
-
引用类型(Reference Types):
- 对象(Object):例如:{name: "John", age: 25}
- 数组(Array):例如:[1, 2, 3, 4]
- 函数(Function):例如:function add(a, b) { return a + b; }
- 正则表达式(Regular Expression):例如:^[0-9]*3$
类型输出:
javascript
let a = 123
let b = 'hello world'
let c = true
let u = undefined
let n = null
let s = Symbol(123)
let big = 123n // bigInt
console.log(typeof a, typeof b, typeof c, typeof u, typeof n, typeof s, typeof big)
//输出:number string boolean undefined object symbol bigint
//对于null输出object类型是一个历史遗留问题,实际上null是一个特殊的原始类型
symbol类型:
Symbol是一种JavaScript的基本数据类型,引入于ES6(ECMAScript 2015)标准。它表示一个独一无二的值,即每个Symbol值都是唯一的,不会重复。
创建Symbol可以使用全局函数Symbol(),它可以接受一个可选的描述参数作为Symbol的标识符。这个描述参数仅用于调试和描述目的,不影响Symbol的唯一性。
下面是一个Symbol的示例:
javascript
//Symbol 创建独一无二的值
let s1 = Symbol('hello')
let s2 = Symbol('hello')
console.log(s1,s2) //输出Symbol(hello) Symbol(hello)
console.log(s1 === s2); //输出false
在上述示例中,我们创建了两个Symbol变量。我们可以通过typeof操作符验证s1和s2的类型为"symbol"。此外,我们还可以注意到s1和s2的值是唯一的,它们之间是不相等的。
Symbol经常用于对象属性的键,可以保证属性名的唯一性。例如:
css
const obj = {
[Symbol("name")]: "John",
[Symbol("age")]: 25,
[Symbol("gender")]: "male"
};
console.log(Object.getOwnPropertySymbols(obj));
// 输出: [ Symbol(name), Symbol(age), Symbol(gender) ]
在这个例子中,我们使用Symbol作为对象obj的属性键,确保每个属性键都是唯一的。通过Object.getOwnPropertySymbols()方法,我们可以获取到对象obj所有Symbol类型的属性键。
需要注意的是,Symbol作为一种基本数据类型,它的值是不可变的,而且不能被强制转换为其他类型。因此,Symbol不能用于进行数学运算或字符串拼接等操作。它主要用于创建唯一的标识符,以及作为特定场景下的对象属性键。
BigInt类型:
BigInt类型用于表示任意精度的整数。BigInt类型的值可以通过在整数字面量后面加上字母"n"来创建,例如:let big = 123n。
BigInt类型可以存储超过JavaScript Number类型所能表示的范围的整数,它可以表示非常大或非常小的整数。BigInt类型的值可以进行基本的数学操作,如加法、减法、乘法和除法等。
javascript
let big = 123n; // 创建一个BigInt类型的值
console.log(typeof big); // 输出 "bigint"
let result = big + 1n; // 进行加法运算
console.log(result); // 输出 124n
// 将BigInt类型转换为Number类型进行计算
let converted = Number(big) + 1;
console.log(converted); // 输出 124
// BigInt类型与Number类型进行混合运算会导致精度损失
let mixed = big + 1;
console.log(mixed); // 输出 124,但精度已损失
正则表达式:
下面是一个正则表达式的实例:假设要匹配一个字符串,这个字符串可以是任意长度的数字串,但是必须以数字"3"结尾。可以使用如下的正则表达式进行匹配:
css
^[0-9]*3$
这个正则表达式的含义是:
- "^"表示匹配字符串的开头;
- "[0-9]*"表示匹配任意长度的数字串;
- "3"表示匹配数字"3";
- "$"表示匹配字符串的结尾。
因此,这个正则表达式可以匹配任意长度的数字串,只要以数字"3"结尾即可。例如,可以匹配"123"、"4567893"、"33"等字符串,但是不能匹配"abc3"、"1a23"等非数字开头或者不以数字"3"结尾的字符串。
二、注意事项:
- 原始类型是不可变的,一旦创建就无法修改。每次对原始类型的操作都会生成一个新的值。
- 引用类型是可变的,可以添加、修改和删除其属性和方法。
- 引用类型的赋值是按引用传递的,即复制的是对象的引用而非实际值。多个变量引用同一个对象时,改变其中一个变量的值会影响其他变量。
- null表示空值,typeof null会返回"object",这是一个历史遗留问题,实际上null是一个特殊的原始类型。
- undefined表示未定义的值,typeof undefined会返回"undefined"。
- Symbol是ES6新增的原始类型,表示唯一的、不可变的值,可以用作对象的属性名。
- BigInt类型只能进行与BigInt类型之间的运算,与其他原始类型(如Number)不能直接进行运算。
- BigInt类型不能与Number类型进行混合运算,需要进行类型转换才能进行计算。
- BigInt类型在进行比较操作时需要使用严格相等运算符(===),因为在相等比较时类型转换会导致精度损失。
三、需要注意的地方:
- 原始类型在传递参数时是按值传递的,函数内部对参数的修改不会影响到外部变量。
- 引用类型在传递参数时是按引用传递的,函数内部对参数的修改会影响到外部变量。
- 在使用引用类型时要注意浅拷贝和深拷贝的问题(后文会做讲解),避免意外修改原始对象。
- 对于字符串(String)、数字(Number)和布尔值(Boolean),尽量使用字面量的方式创建,而不是使用包装对象(String、Number、Boolean)。
- 在判断变量的类型时,建议使用typeof运算符,但对于对象和数组,typeof都会返回"object",需要结合其他方式进行判断。