JavaScript基础语法深度解析:从入门到精通的系统指南

208 阅读4分钟

JavaScript基础语法深度解析:从入门到精通的系统指南

掌握 JavaScript 基础语法是学习前端开发或 Node.js 的关键第一步。下面是一个系统性的学习路径和核心概念梳理:

一、核心基础概念

  1. 变量声明

    • 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
    
  2. 数据类型

    • 基本类型: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() {};   // 函数
    
  3. 数据类型检测

  • typeof 运算符: 返回数据类型的字符串,但是无法区分 null 和 object ,数组/日期等均返回 “object”
  • instanceof 运算符:检测对象是否属于某个构造函数(只适用于引用类型)
  • 数组Array.isArray(arr)
  • NaNNumber.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

三、流程控制

  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("工作日");
    }
    
    
  2. 循环语句

    // 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
    

五、对象与数组

  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: 工程师
    
  2. 面向对象编程

    // 构造函数
    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)); // 6
    

    4.数组迭代方法

    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); // "张三 和 王五"
    

六、特殊机制

  1. 作用域与闭包

    • 闭包是指函数能够记住并访问其词法作用域,即使该函数在其词法作用域之外执行。
    • 函数内部访问外部变量形成闭包
    function createCounter() {
      let count = 0;
      return () => count++; // 返回的函数记住count变量
    }
    const counter = createCounter();
    counter(); // 1
    
  2. this 关键字

    • 普通函数:取决于调用方式(动态绑定)
    • 箭头函数:继承外层 this(静态绑定)

七、常见误区与技巧

  1. 相等性判断

    0 == false   // true (隐式转换)
    0 === false  // false (类型不同)
    
  2. 解构赋值 (ES6+)

    const [a, b] = [1, 2];        // 数组解构
    const { name, age } = person; // 对象解构
    
  3. 模板字符串

    console.log(`Name: ${name}, Age: ${age}`); // 支持换行和表达式
    

学习建议

  1. 实践优先JSFiddle 或浏览器控制台直接写代码测试
  2. 掌握调试 学习使用 console.log() 和浏览器开发者工具
  3. 小项目驱动 尝试实现:计算器、待办事项列表(控制台版)
  4. 阅读文档 MDN JavaScript 指南 是最权威的参考

进阶路线:掌握基础后 → ES6+新特性 → 异步编程(Promise/async-await)→ DOM操作 → 模块化

通过反复练习这些基础概念,你会快速建立JavaScript编程直觉。遇到问题时,记得查阅文档和调试代码是关键!