第二节:变量、数据类型与运算符:JS 的基石
📌 第二节:变量、数据类型与运算符:JS 的基石
目标:理解变量声明、作用域规则,掌握原始类型与引用类型的底层差异,熟练运用运算符。
一、变量:数据的“容器”
1. 变量是什么?
- 类比:变量如同一个带标签的“盒子”,用于存储数据(如数字、文字等)。
- 核心作用:在程序运行中动态存储和修改数据。
2. 变量声明方式
-
var
(ES5 及之前)var userName = "Alice"; // 可重复声明,无块级作用域 var userName = "Bob"; // 不会报错(不推荐)
- 问题:
- 允许重复声明(可能覆盖原值)。
- 无块级作用域(
{}
内声明的变量会“泄漏”到外部)。
- 问题:
-
let
(ES6+ 推荐)let age = 25; let age = 30; // SyntaxError: 重复声明报错
- 改进:
- 块级作用域(
if
、for
内的变量不会污染外部)。 - 禁止重复声明。
- 块级作用域(
- 改进:
-
const
(常量声明)const PI = 3.14; PI = 3.1415; // TypeError: 重新赋值报错
- 规则:
- 声明时必须初始化(不能先声明后赋值)。
- 不可重新赋值(但对象属性可修改,见下文)。
- 规则:
二、数据类型:变量存储的内容
1. 原始类型(Primitive Types)
-
特点:按值传递,存储在栈内存,不可变。
-
类型:
类型 示例 说明 String
"Hello"
字符串,用单/双引号包裹 Number
42
、3.14
整数/浮点数,无 int
/float
区分Boolean
true
、false
逻辑值 Null
null
空值(显式赋值,非对象) Undefined
undefined
未定义(变量未赋值时的默认值) Symbol
Symbol("id")
唯一标识符(ES6+) BigInt
9007199254740991n
大整数(ES2020+) -
示例:
let name = "Alice"; // String let isActive = true; // Boolean let count; // undefined
2. 引用类型(Reference Types)
-
特点:按引用传递,存储在堆内存,可变。
-
类型:
Object
(包括Array
、Function
、Date
等)。- 类比:原始类型是“盒子”,引用类型是“文件柜”(内部有多个抽屉)。
-
示例:
let user = { name: "Alice", age: 25 }; // Object let numbers = [1, 2, 3]; // Array(特殊对象) let greet = function() { console.log("Hi"); }; // Function
三、原始类型 vs 引用类型:底层差异
1. 赋值行为对比
-
原始类型:拷贝值(完全独立)。
let a = 10; let b = a; // b 拷贝了 a 的值 b = 20; console.log(a); // 10(未受影响)
-
引用类型:拷贝引用(共享同一对象)。
let obj1 = { x: 1 }; let obj2 = obj1; // obj2 拷贝了 obj1 的引用 obj2.x = 2; console.log(obj1.x); // 2(原对象被修改)
2. 不可变性
-
原始类型不可变:
let str = "hello"; str[0] = "H"; // 无效!字符串不可变 console.log(str); // "hello"(未改变)
-
引用类型可变:
let arr = [1, 2]; arr.push(3); // 数组可变 console.log(arr); // [1, 2, 3]
3. const
与引用类型
-
const
限制的是引用地址:const obj = { x: 1 }; obj.x = 2; // 合法(对象属性可修改) obj = {}; // 报错!不能重新赋值引用
四、类型检测:typeof
与 instanceof
1. typeof
操作符
-
作用:检测原始类型或
function
。 -
示例:
typeof 42; // "number" typeof "Hi"; // "string" typeof true; // "boolean" typeof undefined; // "undefined" typeof {}; // "object"(注意:null 也返回 "object"!) typeof function() {}; // "function"
2. instanceof
操作符
-
作用:检测对象是否为某构造函数的实例。
-
示例:
let arr = [1, 2]; arr instanceof Array; // true arr instanceof Object; // true(数组是对象的子类)
3. 特殊情况
-
null
的类型:typeof null; // "object"(历史遗留问题,需单独判断)
-
解决方案:
function safeTypeCheck(value) {if (value === null) return "null";return typeof value; }
五、动手实践:变量与类型综合练习
任务 1:变量声明与赋值
// 1. 用 let 声明变量并赋值
let productName = "Laptop";
let price = 999.99;// 2. 修改变量值
price = 899.99;// 3. 尝试用 const 声明价格(会报错吗?为什么?)
// const fixedPrice = 999.99; // 正确
// fixedPrice = 899.99; // 报错!
任务 2:类型判断与转换
// 1. 判断以下变量的类型
let a = 10;
let b = "20";
let c = true;
let d = null;
let e = {};console.log(typeof a, typeof b, typeof c, typeof d, typeof e);// 2. 将 b 转换为 Number 类型并计算 a + b
let numB = Number(b); // 或 +b
console.log(a + numB); // 30
任务 3:引用类型操作
// 1. 创建对象并修改属性
let user = { name: "Alice", age: 25 };
user.age = 26; // 合法// 2. 创建数组并添加元素
let fruits = ["apple", "banana"];
fruits.push("orange");
console.log(fruits); // ["apple", "banana", "orange"]
📌 关键点总结
- 变量声明:
- 优先用
let
(可变)和const
(不可变),避免var
。
- 优先用
- 数据类型:
- 原始类型(按值传递) vs 引用类型(按引用传递)。
- 类型检测:
typeof
用于原始类型,instanceof
用于对象。
- 常见陷阱:
null
的typeof
为"object"
,需单独判断。
🎯 下一节预告
「条件语句与循环:控制程序流程」
- 掌握
if-else
、switch
的实际应用场景。 - 破解
for
循环与forEach
的性能差异。 - 动手实现一个猜数字游戏。
如果需要调整内容深度或补充示例(如更详细的 VSCode 调试配置),可以随时告诉我! 😊