JavaScript基础语法深度解析:从入门到精通的系统指南
掌握 JavaScript 基础语法是学习前端开发或 Node.js 的关键第一步。下面是一个系统性的学习路径和核心概念梳理:
一、核心基础概念
-
变量声明
var(函数作用域,存在变量提升 - 避免使用)let(块级作用域,可重新赋值)const(块级作用域,常量不可重新赋值)
// 1. var - 函数作用域(存在变量提升) var name = "张三"; console.log(name); // "张三" // 2. let - 块级作用域(推荐使用) let age = 25; if (true) { let age = 30; // 独立作用域 console.log(age); // 30 } console.log(age); // 25 // 3. const - 块级作用域常量 const PI = 3.14159; // PI = 3.14; // 报错:Assignment to constant variable -
数据类型
- 基本类型:
string,number,boolean,null,undefined,symbol,bigint - 引用类型:
object(包含数组[]、函数{}等)
// 原始类型(Primitive Types) let str = "Hello"; // 字符串 let num = 42; // 数字 let bool = true; // 布尔值 let nothing = null; // null let notDefined; // undefined (未定义) let sym = Symbol("id"); // Symbol (唯一标识符) let big = 9007199254740991n; // BigInt (大整数) // 引用类型(Reference Types) let obj = { name: "张三" }; // 对象 let arr = [1, 2, 3]; // 数组 let func = function() {}; // 函数 - 基本类型:
-
数据类型检测
- typeof 运算符: 返回数据类型的字符串,但是无法区分 null 和 object ,数组/日期等均返回 “object”
- instanceof 运算符:检测对象是否属于某个构造函数(只适用于引用类型)
- 数组:
Array.isArray(arr) - NaN:
Number.isNaN(value)(比全局的isNaN()更安全) - 其他类型:通过
Object.prototype.toString.call()
// 类型检测
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof Date.now()); //"number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof new Date()); //"object"
console.log(typeof null); // "object" (历史遗留问题)
console.log(typeof []); // "object"
console.log(Array.isArray([])); // true (检测数组)
// 类型检测 - instanceof
console.log([] instanceof Array); //true
console.log(new Date() instanceof Date); //true
console.log('str' instanceof String); // false(字面量不是对象)
console.log(1234 instanceof Number); // false(字面量不是对象)
console.log(null instanceof Object); // false(字面量不是对象)
// 类型检测 -Object.toString.call()
Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(new Date()) // "[object Date]"
// 类型转换
let value = "123";
console.log(Number(value)); // 123 (数字)
console.log(String(123)); // "123" (字符串)
console.log(Boolean("hello")); // true (布尔值)
// 隐式转换
console.log("5" + 2); // "52" (字符串拼接)
console.log("5" - 2); // 3 (数字运算)
console.log("5" * "2"); // 10 (数字运算)
二、运算符与表达式
| 类型 | 运算符示例 | 说明 |
|---|---|---|
| 算术运算符 | + - * / % ** | 注意+ 的字符串拼接行为 |
| 比较运算符 | == === != !== > < | 优先使用严格相等=== |
| 逻辑运算符 | && ! !! | |
| 赋值运算符 | = += -= | let x = 10; x += 5; |
// 算术运算符
console.log(10 + 5); // 15
console.log(10 - 5); // 5
console.log(10 * 5); // 50
console.log(10 / 5); // 2
console.log(10 % 3); // 1 (取余)
console.log(2 ** 3); // 8 (幂运算)
// 比较运算符
console.log(5 == "5"); // true (值相等)
console.log(5 === "5"); // false (严格相等)
console.log(5 != "5"); // false
console.log(5 !== "5"); // true
// 逻辑运算符
console.log(true && false); // false (与)
console.log(true || false); // true (或)
console.log(!true); // false (非)1
三、流程控制
-
条件语句
// if-else if (age > 18) { console.log("Adult"); } else if (age > 13) { console.log("Teen"); } else { console.log("Child"); } // switch switch (color) { case "red": console.log("Stop"); break; default: console.log("Unknown"); } // switch switch (new Date().getDay()) { case 0: console.log("周日"); break; case 6: console.log("周六"); break; default: console.log("工作日"); } -
循环语句
// for 循环 for (let i = 0; i < 5; i++) { console.log(i); } // while 循环 let i = 0; while (i < 5) { console.log(i); i++; } // do-while循环 let k = 0; do { console.log(k); // 0 (至少执行一次) k++; } while (k < 1); // for...of (遍历数组/字符串) for (let char of "Hello") { console.log(char); }
四、函数(核心!)
-
函数定义
// 函数声明 function greet(name) { return `你好, ${name}!`; } console.log(greet("张三")); // 你好, 张三! // 函数表达式 const sum = function(a, b) { return a + b; }; console.log(sum(2, 3)); // 5 // 箭头函数 (ES6+) const multiply = (a, b) => a * b; console.log(multiply(4, 5)); // 20 // 默认参数 function createUser(name, role = "user") { return { name, role }; } console.log(createUser("李四")); // {name: "李四", role: "user"} // 剩余参数 function join(separator, ...items) { return items.join(separator); } console.log(join("-", "a", "b", "c")); // "a-b-c" -
关键特性
- 参数:支持默认值
(a = 1) - 作用域:函数级作用域,闭包
arguments对象(箭头函数无)
- 参数:支持默认值
-
作用域与闭包
作用域:作用域决定了变量和函数的可访问范围
闭包:是指函数能够记住并访问其词法作用域,即使该函数在其词法作用域之外执行。
简单来说:当一个函数可以访问并记住它被声明时所处的环境(包括变量等),即使这个函数在其他地方被调用,就形成了闭包。
// 作用域链 let globalVar = "全局"; function outer() { let outerVar = "外部"; function inner() { let innerVar = "内部"; console.log(globalVar); // "全局" console.log(outerVar); // "外部" console.log(innerVar); // "内部" } inner(); } outer(); // 闭包应用 function createCounter() { let count = 0; return { increment: function() { count++; return count; }, decrement: function() { count--; return count; }, getCount: function() { return count; } }; } const counter = createCounter(); console.log(counter.increment()); // 1 console.log(counter.increment()); // 2 console.log(counter.decrement()); // 1
五、对象与数组
-
对象创建与操作对象字面量
// 对象字面量 const person = { name: "张三", age: 30, greet() { console.log(`你好,我是${this.name}`); } }; person.greet(); // 你好,我是张三 console.log(person["age"]); // 30 (方括号访问) // 添加/删除属性 person.job = "工程师"; // 添加属性 delete person.age; // 删除属性 // 遍历对象 for (const key in person) { console.log(`${key}: ${person[key]}`); } // 输出: // name: 张三 // greet: [Function: greet] // job: 工程师 -
面向对象编程
// 构造函数 function Person(name, age,sex) { this.name = name; this.age = age; this.sex = sex; this.greet = function() { console.log(`你好,我是${this.name},sex`); }; } const person1 = new Person("张三", 30,"男"); person1.greet(); // 你好,我是张三,男 // ES6类语法 class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} 发出声音`); } } class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } speak() { console.log(`${this.name} 汪汪叫!`); } } const myDog = new Dog("小黑", "拉布拉多"); myDog.speak(); // 小黑 汪汪叫!3.常用数组方法
const numbers = [1, 2, 3, 4, 5]; // 添加/删除元素 numbers.push(6); // 末尾添加 [1,2,3,4,5,6] numbers.pop(); // 末尾删除 [1,2,3,4,5] numbers.unshift(0); // 开头添加 [0,1,2,3,4,5] numbers.shift(); // 开头删除 [1,2,3,4,5] // 截取与拼接 const sliced = numbers.slice(1, 3); // [2,3] (不改变原数组) const spliced = numbers.splice(1, 2, 6, 7); // 返回[2,3] 数组变为[1,6,7,4,5] // 查找与判断 console.log(numbers.includes(4)); // true console.log(numbers.indexOf(7)); // 2 console.log(numbers.find(n => n > 3)); // 64.数组迭代方法
const users = [ { id: 1, name: "张三", age: 30 }, { id: 2, name: "李四", age: 25 }, { id: 3, name: "王五", age: 35 } ]; // map - 创建新数组 const names = users.map(user => user.name); console.log(names); // ["张三", "李四", "王五"] // filter - 过滤数组 const over30 = users.filter(user => user.age > 30); console.log(over30); // [{id:3, name:"王五", age:35}] // reduce - 累积计算 const totalAge = users.reduce((sum, user) => sum + user.age, 0); console.log(totalAge); // 90 // forEach - 遍历数组 users.forEach(user => { console.log(`${user.name} 今年 ${user.age} 岁`); }); // 链式调用 const result = users .filter(user => user.age > 25) .map(user => user.name) .join(" 和 "); console.log(result); // "张三 和 王五"
六、特殊机制
-
作用域与闭包
- 闭包是指函数能够记住并访问其词法作用域,即使该函数在其词法作用域之外执行。
- 函数内部访问外部变量形成闭包
function createCounter() { let count = 0; return () => count++; // 返回的函数记住count变量 } const counter = createCounter(); counter(); // 1 -
this关键字- 普通函数:取决于调用方式(动态绑定)
- 箭头函数:继承外层
this(静态绑定)
七、常见误区与技巧
-
相等性判断
0 == false // true (隐式转换) 0 === false // false (类型不同) -
解构赋值 (ES6+)
const [a, b] = [1, 2]; // 数组解构 const { name, age } = person; // 对象解构 -
模板字符串
console.log(`Name: ${name}, Age: ${age}`); // 支持换行和表达式
学习建议
- 实践优先 在 JSFiddle 或浏览器控制台直接写代码测试
- 掌握调试
学习使用
console.log()和浏览器开发者工具 - 小项目驱动 尝试实现:计算器、待办事项列表(控制台版)
- 阅读文档 MDN JavaScript 指南 是最权威的参考
进阶路线:掌握基础后 → ES6+新特性 → 异步编程(Promise/async-await)→ DOM操作 → 模块化
通过反复练习这些基础概念,你会快速建立JavaScript编程直觉。遇到问题时,记得查阅文档和调试代码是关键!