Appearance
08|JavaScript 变量与数据类型
JavaScript 运行在浏览器中,负责处理页面交互、数据计算、网络请求。写 JavaScript 代码时,第一个遇到的问题是:变量怎么声明、能存哪些类型的数据、这些类型之间有什么区别。和 Python 的"赋值即声明"不同,JavaScript 要求先声明再使用,且同一变量不能重复声明。
一、变量声明
JavaScript 用 const 和 let 声明变量:
js
const title = "运维平台"; // const:声明后不能重新赋值
let count = 0; // let:声明后可以重新赋值
// title = "其他"; // 报错:const 变量不可重新赋值
count = count + 1; // 正常能用 const 就用 const,需要重新赋值时才用 let。这样可以从源头上避免"变量被意外修改"的 bug。
旧语法中还有 var,但现代 JavaScript 已不推荐使用:var 存在变量提升(hoisting)和函数作用域问题,在块级结构(如 if、for)中行为不符合直觉。
js
// var 的问题:循环中的计数器泄漏到外部
for (var i = 0; i < 3; i++) {
console.log(i);
}
console.log(i); // 输出 3,i 泄漏到了循环外部
// let 修复了这个问题
for (let j = 0; j < 3; j++) {
console.log(j);
}
// console.log(j); // 报错:j is not defined二、基础数据类型
JavaScript 有 7 种基础类型(primitive types):
| 类型 | 示例 | 说明 |
|---|---|---|
string | "hello" | 字符串,用单引号或双引号包裹 |
number | 42、3.14 | 数字,不分整数和浮点数 |
boolean | true、false | 布尔值 |
null | null | 主动设为空值 |
undefined | undefined | 变量声明但未赋值时的默认值 |
bigint | 9007199254740991n | 大整数,日常开发很少用到 |
symbol | Symbol("id") | 唯一标识符,日常开发很少用到 |
字符串
js
const name = "运维平台";
const desc = '资产管理与任务调度';
// 字符串长度
console.log(name.length); // 4
// 取单个字符
console.log(name[0]); // "运"
// 模板字符串(用反引号,支持插值)
const version = "v1.0";
const fullName = `${name} ${version}`; // "运维平台 v1.0"字符串创建后不可变:
js
const s = "hello";
s[0] = "H"; // 不会报错,但也不会生效
console.log(s); // 仍然是 "hello""修改"字符串的操作(如 replace、toUpperCase)都返回新字符串,原字符串不变。
数字
js
const port = 8080;
const rate = 0.95;
// 特殊值
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log("abc" / 2); // NaN(Not a Number)JavaScript 的数字都是 64 位浮点数,没有独立的整数类型。超大整数运算可能产生精度误差:
js
console.log(0.1 + 0.2); // 0.30000000000000004,不是精确的 0.3需要精确小数时(如金额计算),先把数字转为整数运算,再除回去;或者使用专门的库。
布尔值
js
const isRunning = true;
const hasError = false;null 与 undefined
js
let a = null; // 主动设为空
let b; // 声明了但没赋值,默认值是 undefined
console.log(a); // null
console.log(b); // undefinednull 和 undefined 都表示"没有值",但语义不同:null 是主动设为空,undefined 是被动缺失。从后端 API 拿数据时,某个字段没返回就是 undefined,要留意区分。
三、对象
对象是一组键值对的集合:
js
const server = {
hostname: "web-01",
ip: "192.168.1.10",
status: "running",
tags: ["nginx", "api"],
};
// 访问属性
console.log(server.hostname); // "web-01"
console.log(server["ip"]); // "192.168.1.10"
// 修改属性
server.status = "stopped";
// 新增属性
server.env = "production";
// 删除属性
delete server.env;对象属性名是字符串(不用引号时会被自动转字符串)。如果属性名包含特殊字符或空格,必须用引号:
js
const obj = {
"server-name": "web-01", // 属性名含连字符,必须引号
};
console.log(obj["server-name"]);对象声明为 const 时,变量本身不能重新赋值,但对象的属性可以修改:
js
const config = { port: 8080 };
config.port = 9090; // 可以
// config = { port: 9090 }; // 报错:const 变量不可重新赋值四、数组
数组是有序的元素集合:
js
const services = ["nginx", "redis", "mysql"];
// 访问元素(索引从 0 开始)
console.log(services[0]); // "nginx"
console.log(services.length); // 3
// 修改元素
services[1] = "postgres";
// 添加元素
services.push("elasticsearch"); // 末尾添加
services.unshift("haproxy"); // 开头添加
// 删除元素
services.pop(); // 删除末尾,返回被删元素
services.shift(); // 删除开头,返回被删元素数组可以混存不同类型的元素(不推荐):
js
const mixed = ["hello", 42, true, { a: 1 }];五、typeof 检测类型
js
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof {}); // "object"
console.log(typeof []); // "object"(数组也是对象)
console.log(typeof null); // "object"(历史 bug,记住即可)
console.log(typeof undefined); // "undefined"
console.log(typeof function(){}); // "function"数组的判断需要用 Array.isArray:
js
const arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
console.log(typeof arr); // "object",无法区分六、类型转换
显式转换
js
const numStr = "8080";
// 字符串转数字
const port = Number(numStr); // 8080
const port2 = parseInt(numStr, 10); // 8080,第二个参数是进制
// 数字转字符串
const str = String(8080); // "8080"
const str2 = (8080).toString(); // "8080"
// 转布尔值
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean("hello")); // true隐式转换(避免依赖)
js
console.log("5" + 3); // "53"(数字被转成字符串,执行拼接)
console.log("5" - 3); // 2(字符串被转成数字,执行减法)
console.log("5" == 5); // true(== 会做类型转换后比较)
console.log("5" === 5); // false(=== 不做转换,类型不同直接不相等)推荐始终使用 === 和 !==,避免隐式转换带来的意外行为。
七、常见错误
用 const 声明后试图修改
js
const count = 0;
count = 1; // TypeError: Assignment to constant variable如果变量需要重新赋值,用 let。
对象属性访问用错引号
js
const obj = { "server-name": "web-01" };
// 错误
console.log(obj.server-name); // 被解析为 obj.server - name,NaN
// 正确
console.log(obj["server-name"]);用 typeof 判断数组
js
const arr = [1, 2, 3];
// 错误
if (typeof arr === "object") { // 对象也满足这个条件
// ...
}
// 正确
if (Array.isArray(arr)) {
// ...
}混淆 null 和 undefined
js
// 后端 API 返回的数据
const data = { name: "server" };
console.log(data.name); // "server"
console.log(data.status); // undefined(字段不存在)
// 主动清空
let user = { name: "admin" };
user = null;
console.log(user); // null