1、Javascript 有多少种数据类型,如何判断?
JavaScript 有两种不同的数据类型集:原始类型和对象类型。
原始类型包括:
- Undefined :一个未赋值的变量会有一个默认值
undefined
。 - Null :表示一个空值(注意
typeof null
返回"object"
,这实际上是一个历史遗留的错误)。 - Boolean :有两个值
true
和false
。 - Number:表示整数和浮点数。
- String:表示文本数据。
- Symbol(ES6 新增):表示唯一的、不可变的数据值,常用作对象属性的键。
- BigInt (ES2020 新增):表示大于
2^53 - 1
的整数。
对象类型包括:
- Object:表示一个实例对象,可以包含一组键值对。
判断数据类型的方法:
- 使用
typeof
操作符可以判断一个变量是否为原始类型(除了null
,typeof null
会返回"object"
)。 - 使用
instanceof
操作符可以判断一个对象是否为某个构造函数的实例。 - 使用
Object.prototype.toString.call()
方法可以得到对象的类内部属性,这是一个更准确的类型检测方法。
例如:
javascript
typeof 42; // "number"
typeof 'JavaScript'; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof Symbol('sym'); // "symbol"
typeof BigInt(1234567890123456789012345678901234567890); // "bigint"
typeof null; // "object"(这是一个历史遗留的错误)
typeof {}; // "object"
typeof []; // "object"
typeof function() {}; // "function"(函数在 JavaScript 中是对象的一种特殊类型)
// 更准确的类型检测
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(new Date()); // "[object Date]"
注意,虽然函数在 JavaScript 中被视为对象,但 typeof
对函数返回的是 "function"
。
2、为什么说 Symbol 是基本数据类型?
Symbol
被认为是基本数据类型(也称为原始数据类型),因为它满足基本数据类型的特征:
- 不可变性 :
Symbol
的值是不可变的,一旦创建,就不能修改。 - 唯一性 :每个
Symbol
的值都是唯一的,即使它们有相同的描述也不相等。 - 不可构造 :
Symbol
不是对象,不能使用new
关键字来构造,它是通过调用Symbol
函数来创建的。
由于这些特性,Symbol
类型的值可以用作对象属性的键,而不必担心属性名冲突。这使得 Symbol
成为一种适合用作唯一标识符的基本数据类型。
3、JavaScript中基本数据类型有哪些特征?
JavaScript 中的基本数据类型(原始数据类型)具有以下特征:
- 不可变性:基本数据类型的值是不可变的。当对这种类型的值进行操作时,实际上是创建了一个新值。
- 按值传递:基本数据类型的值在赋值或传递给函数时,都是按值传递的。这意味着会创建一个副本。
- 没有属性或方法 :基本数据类型本身不是对象,因此没有可以调用的属性或方法。但是,JavaScript 会自动将基本数据类型包装成对象,以便可以调用方法,如字符串的
.length
属性或.toUpperCase()
方法。 - 存储位置:基本数据类型的值通常存储在栈内存中,这使得访问这些值非常快。
基本数据类型包括:Undefined
、Null
、Boolean
、Number
、String
、Symbol
和 BigInt
。
4、基本类型为什么也可以调方法,比如.toFixed() ?
尽管基本数据类型(如 Number
和 String
)本身不是对象,因此没有方法,但 JavaScript 在需要时会临时将它们转换(或称为"包装")为对象,以便可以调用方法。这个过程通常被称为"自动装箱"。
例如,当你调用一个数值的 .toFixed()
方法时,JavaScript 会临时创建一个 Number
对象,让你能够使用 Number
对象提供的方法。调用方法后,这个临时对象就会被丢弃,你继续持有的是原始的基本类型值。
这个过程是透明的,所以看起来就像基本类型值本身就有方法可以调用。实际上,这些方法是定义在原始类型对应的原型对象上的,例如 Number.prototype.toFixed
、String.prototype.toUpperCase
等。