01-变量与数据类型
分类:01-JavaScript基础核心
发布于:
阅读时间:28 分钟
变量与数据类型
📋 学习目标
- 掌握JavaScript中三种变量声明方式的区别
- 理解JavaScript的7种基本数据类型
- 学会正确使用类型转换
- 了解变量作用域和提升机制
🎯 核心概念
1. 变量声明方式
JavaScript提供了三种变量声明方式:var、let和const,它们有重要的区别:
var 的特点
// 1. 变量提升 - 可以先使用后声明
console.log(name); // undefined,不会报错
var name = "张三";
// 2. 函数作用域 - 只在函数内有效
function test() {
if (true) {
var localVar = "局部变量";
}
console.log(localVar); // 可以访问
}
// 3. 可以重复声明
var a = 1;
var a = 2; // 允许
let 的特点
// 1. 块级作用域 - 只在代码块内有效
if (true) {
let blockVar = "块级变量";
}
// console.log(blockVar); // 报错:blockVar is not defined
// 2. 暂时性死区 - 必须先声明后使用
// console.log(letVar); // 报错:Cannot access 'letVar' before initialization
let letVar = "let变量";
// 3. 不允许重复声明
let b = 1;
// let b = 2; // 报错:Identifier 'b' has already been declared
const 的特点
// 1. 声明时必须初始化
// const constant; // 报错:Missing initializer in const declaration
// 2. 值不能重新赋值
const PI = 3.14159;
// PI = 3.14; // 报错:Assignment to constant variable
// 3. 对于引用类型,可以修改属性
const obj = { name: "对象" };
obj.name = "修改后的对象"; // 允许
// obj = {}; // 报错:Assignment to constant variable
2. 数据类型详解
JavaScript有7种基本数据类型和1种引用类型:
基本数据类型
// 1. Number - 数字
let num = 42;
let floatNum = 3.14;
let infinity = Infinity;
let notANumber = NaN;
// 2. String - 字符串
let str1 = "双引号字符串";
let str2 = '单引号字符串';
let str3 = `模板字符串,可以嵌入变量:${num}`;
// 3. Boolean - 布尔值
let isTrue = true;
let isFalse = false;
// 4. Undefined - 未定义
let undefinedVar;
console.log(undefinedVar); // undefined
// 5. Null - 空值
let nullVar = null;
console.log(typeof nullVar); // "object" (这是一个历史遗留的bug)
// 6. Symbol - 符号(ES6新增)
let sym = Symbol("描述");
let sym2 = Symbol("描述");
console.log(sym === sym2); // false,每个Symbol都是唯一的
// 7. BigInt - 大整数(ES2020新增)
let bigNum = 9007199254740991n;
let bigNum2 = 123n;
引用数据类型
// Object - 对象
let person = {
name: "张三",
age: 25,
greet: function() {
return `你好,我是${this.name}`;
}
};
// Array - 数组
let arr = [1, 2, 3, "字符串", { obj: "对象" }];
// Function - 函数
function add(a, b) {
return a + b;
}
// Date - 日期
let date = new Date();
// RegExp - 正则表达式
let reg = /\d+/g;
3. 类型转换
显式类型转换
// 转换为字符串
String(123); // "123"
String(true); // "true"
String(null); // "null"
String(undefined); // "undefined"
// 转换为数字
Number("123"); // 123
Number("123.45"); // 123.45
Number("123abc"); // NaN
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
// 转换为布尔值
Boolean(0); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean("false"); // true
Boolean("0"); // true
// parseInt 和 parseFloat
parseInt("123"); // 123
parseInt("123px"); // 123
parseInt("123.45"); // 123
parseFloat("123.45"); // 123.45
parseFloat("123.45px"); // 123.45
隐式类型转换
// 字符串拼接
console.log(1 + "2"); // "12"
console.log("1" + 2); // "12"
// 数字运算
console.log("1" - 2); // -1
console.log("1" * 2); // 2
console.log("1" / 2); // 0.5
// 布尔运算
console.log(1 <mark> true); // true
console.log(0 </mark> false); // true
console.log("" <mark> false); // true
// 严格相等(推荐使用)
console.log(1 </mark>= true); // false
console.log(0 =<mark> false); // false
console.log("" </mark>= false); // false
4. 变量作用域
// 全局作用域
var globalVar = "全局变量";
function outerFunction() {
// 函数作用域
var outerVar = "外部函数变量";
let outerLet = "外部函数let";
function innerFunction() {
// 内层函数作用域
var innerVar = "内部函数变量";
console.log(globalVar); // 可以访问全局变量
console.log(outerVar); // 可以访问外部函数变量
console.log(innerVar); // 可以访问内部变量
}
innerFunction();
// console.log(innerVar); // 报错:无法访问内部变量
}
outerFunction();
// console.log(outerVar); // 报错:无法访问函数内部变量
🔧 实践练习
练习1:变量声明方式对比
// 分析以下代码的输出结果
function testVar() {
console.log(a); // undefined (变量提升)
if (true) {
var a = 1;
let b = 2;
const c = 3;
}
console.log(a); // 1 (var是函数作用域)
// console.log(b); // 报错 (let是块级作用域)
// console.log(c); // 报错 (const是块级作用域)
}
testVar();
练习2:类型转换理解
// 预测输出结果
console.log([] <mark> ![]); // true
console.log([] </mark> []); // false
console.log({} <mark> {}); // false
console.log(NaN </mark> NaN); // false
console.log(NaN === NaN); // false
⚠️ 常见陷阱
1. 变量提升陷阱
// ❌ 错误示例
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i); // 输出:3, 3, 3
}, 100);
}
// ✅ 正确做法
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i); // 输出:0, 1, 2
}, 100);
}
2. 类型判断陷阱
// ❌ 使用typeof判断数组
console.log(typeof []); // "object"
// ✅ 正确判断数组的方法
console.log(Array.isArray([])); // true
console.log([] instanceof Array); // true
console.log(Object.prototype.toString.call([])); // "[object Array]"
3. null与undefined的区别
// null表示"无值",是显式设置的
let data = null;
// undefined表示"未定义",是默认状态
let data2;
console.log(data2); // undefined
// 类型判断
console.log(typeof null); // "object"
console.log(typeof undefined); // "undefined"
📝 最佳实践
- 优先使用const:只有在需要重新赋值时才使用let
- 避免使用var:在现代JavaScript开发中不再推荐使用var
- 使用严格相等:优先使用
=<mark>而不是</mark> - 显式类型转换:避免依赖隐式类型转换,代码更清晰
- 合理命名:使用有意义的变量名,遵循命名规范
🎯 小结
- 掌握了
var、let、const的区别和使用场景 - 理解了JavaScript的8种数据类型
- 学会了显式和隐式类型转换
- 了解了变量作用域和常见陷阱
- 掌握了变量声明的最佳实践
下一步学习:函数与作用域