数据类型
相关信息
JavaScript 是一种动态类型语言,这意味着变量可以随时更改其类型。JavaScript 的数据类型分为两大类:原始类型(Primitive types) 和 引用类型(Reference types)。
原始类型
原始类型是不可变的、直接存储在变量中的值。JavaScript 中有 7 种原始类型。
- Number:用于表示整数和浮点数。
- String:用于表示文本数据,即字符串。
- Boolean:表示逻辑值 true 或 false。
- Undefined:表示变量已声明但未赋值。
- Null:表示空或不存在的值。null 是一个赋值,可以表示对象的缺失。
- Symbol:表示唯一的标识符,常用于对象的属性键。
- BigInt:用于表示大整数,超出 Number 类型的安全范围。
let num1 = 42;
let num2 = 3.14;
let greeting = "Hello, World!";
let isLoggedIn = true;
let x; // x 是 undefined
let y = null;
let sym = Symbol('unique');
let bigIntNum = BigInt(9007199254740991); // 或者使用字面量 `9007199254740991n`
Number 类型的属性和方法
属性 :
Number.MAX_VALUE
: 能表示的最大数值。Number.MIN_VALUE
: 能表示的最小正数值(接近 0 的最小数)。Number.POSITIVE_INFINITY
: 正无穷大。Number.NEGATIVE_INFINITY
: 负无穷大。Number.NaN
: 表示非数字的特殊值。
常用方法 :
toFixed(digits)
: 将数字格式化为指定小数位的字符串。toString(radix)
: 将数字转换为字符串,可以指定进制(默认为 10 进制)。parseInt()
: 将字符串转换为整数。parseFloat()
: 将字符串转换为浮点数。
let num = 123.456;
console.log(num.toFixed(2)); // "123.46"
console.log(num.toString(16)); // "7b.74"
String 类型的属性和方法
属性 :
length
: 字符串的长度。
常用方法 :
charAt(index)
: 返回指定位置的字符。concat()
: 连接两个或多个字符串。includes(substring)
: 检查字符串是否包含子字符串,返回布尔值。indexOf(substring)
: 返回子字符串首次出现的位置。slice(start, end)
: 提取字符串的一部分,返回一个新字符串。toUpperCase() / toLowerCase()
: 将字符串转换为大写或小写。trim()
: 移除字符串两端的空白符。
let str = "Hello, JavaScript!";
console.log(str.length); // 18
console.log(str.charAt(0)); // "H"
console.log(str.includes("Java")); // true
console.log(str.slice(7, 17)); // "JavaScript"
Boolean 类型的属性和方法
Boolean 类型没有专门的属性和方法,布尔值 true 和 false 作为原始类型,只能用于逻辑操作。
Array 类型的属性和方法
属性:
length
: 数组的长度(元素的数量)。
常用方法:
push(element)
: 向数组末尾添加一个或多个元素。pop()
: 删除数组的最后一个元素,并返回该元素。shift()
: 删除数组的第一个元素,并返回该元素。unshift(element)
: 向数组的开头添加一个或多个元素。concat(array)
: 合并两个或多个数组。slice(start, end)
: 返回数组的一部分。splice(start, deleteCount, items...)
: 修改数组内容,添加或删除元素。forEach(callback)
: 对数组的每个元素执行一次提供的函数。map(callback)
: 对数组的每个元素执行一次提供的函数,并返回一个新的数组。filter(callback)
: 创建一个新数组,包含所有通过测试的元素。
let arr = [1, 2, 3, 4, 5];
arr.push(6);
console.log(arr); // [1, 2, 3, 4, 5, 6]
let newArr = arr.filter(num => num > 3);
console.log(newArr); // [4, 5, 6]
Object 类型的属性和方法
常用方法 :
Object.keys(obj)
: 返回对象的所有键组成的数组。Object.values(obj)
: 返回对象的所有值组成的数组。Object.entries(obj)
: 返回对象的键值对组成的二维数组。hasOwnProperty(prop)
: 检查对象是否拥有指定的属性(而不是继承来的属性)。
let user = { name: "Alice", age: 25 };
console.log(Object.keys(user)); // ["name", "age"]
console.log(user.hasOwnProperty("name")); // true
引用类型
引用类型存储的是对象的引用,而不是对象的实际值。JavaScript 中常见的引用类型有:
- Object:表示键值对的集合,或复杂的数据结构。
- Array:用于存储有序列表的数据。
- Function:函数也是对象的一种特殊类型,可以被调用。
- Date、RegExp(正则表达式)等也是对象类型。
let user = {
name: "Alice",
age: 25
};
let arr = [1, 2, 3];
function greet() {
console.log("Hello!");
}
包装类型
JavaScript 提供了一种称为 包装类型 的机制,使得原始类型可以像对象一样操作。每当你对一个原始值执行类似对象的操作时,JavaScript 会临时将其转换为相应的包装对象。
JavaScript 中三种常见的包装类型是:
Number
对应number
原始类型。String
对应string
原始类型。Boolean
对应boolean
原始类型。
自动装箱
当我们尝试访问原始类型的属性或方法时,JavaScript 会临时将该原始值包装成对象。例如,当你对一个字符串使用 length 属性时,JavaScript 会将它包装为一个 String 对象:
let str = "Hello";
console.log(str.length); // 5
// 背后执行了以下操作:
let temp = new String(str);
console.log(temp.length); // 5
temp = null; // 使用完后被销毁
手动创建包装对象
包装类型的对象可以手动创建,但通常不建议这样做,因为这会导致性能下降和混淆。
let numObj = new Number(100);
let strObj = new String("Hello");
let boolObj = new Boolean(true);
注意
尽管原始类型和它们的包装对象可以互相转换,但它们在类型上是不同的。
let num1 = 42;
let num2 = new Number(42);
console.log(typeof num1); // "number"
console.log(typeof num2); // "object"
console.log(num1 == num2); // true,自动类型转换
console.log(num1 === num2); // false,严格比较类型不同
包装类的局限
由于包装对象是临时创建的,并且在访问结束后立即销毁,所以它们并不能保存修改。例如:
let str = "hello";
str.test = 5; // 临时包装为 String 对象并添加属性
console.log(str.test); // undefined,包装对象被销毁,属性丢失
const
const 声明的变量不能重新赋值,但如果 const 用于声明一个引用类型(如对象或数组),你仍然可以修改该对象的属性或数组的元素。
const obj = { name: 'Alice' };
obj.name = 'Bob'; // 允许修改对象的属性
console.log(obj.name); // 输出: 'Bob'
const arr = [1, 2, 3];
arr.push(4); // 允许修改数组内容
console.log(arr); // 输出: [1, 2, 3, 4]
但是,你不能将一个新的对象或数组赋值给使用 const 声明的变量:
obj = {}; // 会抛出 TypeError: Assignment to constant variable
数据类型之间的转换
JavaScript 提供了多种方法来进行隐式和显式的类型转换。
隐式转换
JavaScript 在特定情况下会自动进行类型转换,例如在算术运算中:
- 字符串和数字的相加:数字会被转换为字符串。
- 布尔值和数字的转换:true 转为 1,false 转为 0。
let result = 5 + "10"; // "510"
let result = true + 1; // 2
显式转换
字符串转换为数字:
- 使用
Number()
将字符串转换为数字。 - 使用
parseInt()
将字符串转换为整数。 - 使用
parseFloat()
将字符串转换为浮点数。
let num = Number("42"); // 42
let intNum = parseInt("42.58"); // 42
let floatNum = parseFloat("42.58"); // 42.58
数字转换为字符串:
- 使用
String()
将数字转换为字符串。 - 使用
toString()
方法。
let strNum = String(42); // "42"
let strNum = (42).toString(); // "42"
布尔值转换:
- 使用
Boolean()
将值转换为布尔类型。以下值被转换为 false:0、""(空字符串)、null、undefined 和 NaN,其他所有值都为 true。
let boolValue = Boolean(0); // false
let boolValue = Boolean("hello"); // true
对象转换为字符串或数字:
- 对象的
toString()
方法通常用于将对象转换为字符串。 - 对象的
valueOf()
方法用于获取对象的原始值,通常在算术操作中使用。
let obj = { valueOf: () => 42 };
console.log(obj + 2); // 44
数据类型的判断方式
JavaScript 提供了多种方法来判断数据类型。
typeof 运算符
用于判断变量的数据类型,返回一个字符串。适用于原始类型和函数。
typeof 42; // "number"
typeof "Hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof function() {}; // "function"
typeof null; // "object" (这是一个历史遗留的 bug)
typeof {}; // "object"
instanceof 运算符
用于判断某个对象是否是特定类的实例,通常用于判断引用类型。
let arr = [];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true
Array.isArray() 方法
用于专门判断是否是数组,因为 typeof 对数组返回 "object",无法准确判断数组。
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
Object.prototype.toString.call() 方法
通常用来精确判断数据类型,特别是可以准确判断 null 和 undefined.
Object.prototype.toString.call(42); // "[object Number]"
Object.prototype.toString.call("Hello"); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"
变量命名
- 由字母(a-z A-Z)、数字(0-9)、下划线(_)、美元符号($)组成,不能以数字开头。
- 严格区分大小写。
- 不能是关键字和保留字。
- 遵守驼峰命名法,且变量名必须有意义。