Skip to content

08|JavaScript 变量与数据类型

JavaScript 运行在浏览器中,负责处理页面交互、数据计算、网络请求。写 JavaScript 代码时,第一个遇到的问题是:变量怎么声明、能存哪些类型的数据、这些类型之间有什么区别。和 Python 的"赋值即声明"不同,JavaScript 要求先声明再使用,且同一变量不能重复声明。

一、变量声明

JavaScript 用 constlet 声明变量:

js
const title = "运维平台";     // const:声明后不能重新赋值
let count = 0;               // let:声明后可以重新赋值

// title = "其他";           // 报错:const 变量不可重新赋值
count = count + 1;           // 正常

能用 const 就用 const,需要重新赋值时才用 let。这样可以从源头上避免"变量被意外修改"的 bug。

旧语法中还有 var,但现代 JavaScript 已不推荐使用:var 存在变量提升(hoisting)和函数作用域问题,在块级结构(如 iffor)中行为不符合直觉。

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"字符串,用单引号或双引号包裹
number423.14数字,不分整数和浮点数
booleantruefalse布尔值
nullnull主动设为空值
undefinedundefined变量声明但未赋值时的默认值
bigint9007199254740991n大整数,日常开发很少用到
symbolSymbol("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"

"修改"字符串的操作(如 replacetoUpperCase)都返回新字符串,原字符串不变。

数字

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);      // undefined

nullundefined 都表示"没有值",但语义不同: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