js中 ES6 新特性详解

ES6(ECMAScript 2015)是 JavaScript 的一次重大更新,引入了许多新的特性,使 JavaScript 代码更加简洁、可读和高效。以下是 ES6 的主要新特性及其原理

1. let 和 const 关键字

原理解析

1.1 作用域

  • var 关键字的作用域 :在 ES5 及之前,JavaScript 只有函数作用域 (Function Scope),即 var 声明的变量只在函数内部可见,但在块级 {} 内仍然可以访问:

    javascript 复制代码
    if (true) {
        var x = 10;
    }
    console.log(x); // 10,x 仍然可访问

    由于 xvar 声明的,它的作用域扩展到整个函数或全局,而非 if 代码块内部。

  • letconst 关键字的作用域

    • letconst块级作用域(Block Scope) ,即它们声明的变量只在当前代码块 {} 内有效
    • 这避免了 var 可能导致的全局污染问题。
    javascript 复制代码
    if (true) {
        let y = 20;
    }
    console.log(y); // ReferenceError: y is not defined

1.2 暂时性死区(Temporal Dead Zone, TDZ)

  • letconst 不会像 var 一样变量提升 (Hoisting),而是进入暂时性死区,直到执行到变量声明的位置,变量才可用。

    javascript 复制代码
    console.log(a); // ReferenceError: Cannot access 'a' before initialization
    let a = 10;

    解释

    • 代码在执行时,会先创建变量的作用域。
    • 但是 let 声明的变量在作用域创建后,直到真正声明前,处于"暂时性死区"。
    • 只有 let a = 10; 执行后,a 才能被访问。

1.3 const 的特性

  • const 声明的变量不可被重新赋值

    javascript 复制代码
    const pi = 3.14;
    pi = 3.14159; // TypeError: Assignment to constant variable.
  • 但是对象类型(数组、对象)可以修改其内容

    javascript 复制代码
    const obj = { name: "Alice" };
    obj.name = "Bob"; // 允许修改对象的属性
    console.log(obj); // { name: "Bob" }

    解释

    • const 只是确保 obj 这个变量的引用地址不会变,但对象的内部属性仍然可以修改。

2. 模板字符串(Template Literals)

原理解析

2.1 变量插值

  • 传统字符串拼接需要 + 号,而模板字符串可以使用 ${} 插入变量:

    javascript 复制代码
    let name = "Alice";
    let greeting = `Hello, ${name}!`;
    console.log(greeting); // "Hello, Alice!"

2.2 多行字符串

  • 传统的字符串换行必须使用 \n

    javascript 复制代码
    let str = "Hello\nWorld";
  • 但模板字符串可以直接换行

    javascript 复制代码
    let str = `Hello
    World`;
    console.log(str);

3. 箭头函数(Arrow Functions)

原理解析

3.1 this 绑定机制

  • 普通 functionthis 由调用者决定 ,但箭头函数的 this定义时的作用域 决定:

    javascript 复制代码
    function normalFunction() {
        console.log(this); // this 取决于调用方式
    }
    
    const arrowFunction = () => {
        console.log(this); // this 由定义时决定
    };
  • 事件回调、定时器、map/filter 中,箭头函数可以避免 this 绑定问题:

javascript 复制代码
const obj = {
    value: 10,
    method: function () {
        setTimeout(() => {
            console.log(this.value); // 10
        }, 1000);
    }
};
obj.method();

解释

  • setTimeout 里的回调是箭头函数,this 保持 method 里的 this,即 obj

3.2 语法简化

  • 省略 function 关键字:

    javascript 复制代码
    const add = (a, b) => a + b;
  • 单个参数可省略括号:

    javascript 复制代码
    const square = x => x * x;

4. 解构赋值(Destructuring Assignment)

原理解析

4.1 数组解构

  • 直接提取数组元素:

    javascript 复制代码
    let [a, b, c] = [1, 2, 3];
    console.log(a, b, c); // 1, 2, 3
  • 跳过某些元素

    javascript 复制代码
    let [first, , third] = [10, 20, 30];
    console.log(first, third); // 10, 30

4.2 对象解构

  • 提取对象属性:

    javascript 复制代码
    let { name, age } = { name: "Alice", age: 25 };
    console.log(name, age); // "Alice", 25
  • 给解构变量赋别名

    javascript 复制代码
    let { name: userName } = { name: "Alice" };
    console.log(userName); // "Alice"

4.3 默认值

  • 如果解构的值 undefined,可提供默认值:

    javascript 复制代码
    let { x = 10 } = {};
    console.log(x); // 10

5. 默认参数(Default Parameters)

原理解析

5.1 传统方式

  • 过去需要手动检查参数:

    javascript 复制代码
    function greet(name) {
        name = name || "Guest"; // 传统方式
        console.log(`Hello, ${name}!`);
    }
    greet(); // "Hello, Guest!"

5.2 ES6 语法

  • 直接在参数定义时提供默认值:

    javascript 复制代码
    function greet(name = "Guest") {
        console.log(`Hello, ${name}!`);
    }
    greet(); // "Hello, Guest!"
  • 默认参数只在传 undefined 时生效null 仍会覆盖默认值:

    javascript 复制代码
    greet(null); // "Hello, null!"

6. 扩展运算符(Spread Operator, ...)

原理解析

6.1 用于数组

  • 展开数组元素 :使用 ... 运算符将数组的每一项展开,可以合并数组、拷贝数组,甚至将数组插入到另一个数组中。

    javascript 复制代码
    let arr1 = [1, 2, 3];
    let arr2 = [...arr1, 4, 5];
    console.log(arr2); // [1, 2, 3, 4, 5]
  • 拷贝数组:创建一个新数组,避免修改原数组:

    javascript 复制代码
    let arr1 = [1, 2, 3];
    let arr2 = [...arr1];
    arr2.push(4);
    console.log(arr1); // [1, 2, 3]
    console.log(arr2); // [1, 2, 3, 4]

6.2 用于对象

  • 展开对象的属性:

    javascript 复制代码
    let obj1 = { name: "Alice", age: 25 };
    let obj2 = { ...obj1, city: "New York" };
    console.log(obj2); // { name: "Alice", age: 25, city: "New York" }
  • 合并对象

    javascript 复制代码
    let obj1 = { name: "Alice" };
    let obj2 = { age: 25 };
    let obj3 = { ...obj1, ...obj2 };
    console.log(obj3); // { name: "Alice", age: 25 }

6.3 与函数参数结合使用

  • 直接展开数组作为函数参数:

    javascript 复制代码
    function sum(a, b, c) {
        return a + b + c;
    }
    let nums = [1, 2, 3];
    console.log(sum(...nums)); // 6

7. 对象增强语法(Enhanced Object Literals)

原理解析

7.1 属性简写

  • 如果对象字面量中的键名与变量名相同,可以省略键名:

    javascript 复制代码
    let name = "Alice";
    let person = { name };
    console.log(person); // { name: "Alice" }

7.2 方法简写

  • 定义对象方法时,不再需要 function 关键字:

    javascript 复制代码
    let person = {
        greet() {
            console.log("Hello!");
        }
    };
    person.greet(); // "Hello!"

7.3 动态属性名

  • 对象的属性名可以动态设置,使用方括号 []

    javascript 复制代码
    let propName = "age";
    let person = {
        [propName]: 25
    };
    console.log(person.age); // 25

8. for...of 迭代器

原理解析

8.1 迭代器(Iterator)

  • for...of 用于迭代 对象,尤其适用于数组、字符串、SetMap 等可迭代对象。

    javascript 复制代码
    let arr = [1, 2, 3];
    for (let value of arr) {
        console.log(value); // 1, 2, 3
    }

8.2 与 for...in 的区别

  • for...in 遍历对象的属性名 ,而 for...of 遍历对象的值

    javascript 复制代码
    let arr = [10, 20, 30];
    
    for (let key in arr) {
        console.log(key); // 0, 1, 2(索引)
    }
    
    for (let value of arr) {
        console.log(value); // 10, 20, 30(元素值)
    }

8.3 可迭代对象

  • 迭代对象必须实现 [Symbol.iterator]() 方法,如 Array, String, Map, Set 等。

    javascript 复制代码
    let str = "Hello";
    for (let char of str) {
        console.log(char); // H, e, l, l, o
    }

9. MapSet

原理解析

9.1 Map

  • Map 是一个键值对集合,支持任意类型的键(不仅仅是字符串),并且有序(按插入顺序存储)。

    javascript 复制代码
    let map = new Map();
    map.set("name", "Alice");
    map.set(1, "one");
    console.log(map.get("name")); // Alice
    console.log(map.get(1)); // one
  • Map 还支持直接遍历:

    javascript 复制代码
    for (let [key, value] of map) {
        console.log(key, value); // name Alice, 1 one
    }

9.2 Set

  • Set 是一个值的集合,其中每个值都是唯一的,不允许重复。

    javascript 复制代码
    let set = new Set([1, 2, 3, 3, 4]);
    console.log(set); // Set { 1, 2, 3, 4 }
  • Set 可以用来自动去重:

    javascript 复制代码
    let arr = [1, 2, 3, 3, 4];
    let uniqueArr = [...new Set(arr)];
    console.log(uniqueArr); // [1, 2, 3, 4]

10. 类(Class)

原理解析

10.1 类的定义

  • ES6 引入了更直观的 class 语法,进行面向对象编程:

    javascript 复制代码
    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        
        greet() {
            console.log(`Hello, I'm ${this.name}`);
        }
    }
    
    let p = new Person("Alice", 25);
    p.greet(); // "Hello, I'm Alice"

10.2 类的继承

  • class 还支持继承,使用 extends 关键字:

    javascript 复制代码
    class Student extends Person {
        constructor(name, age, grade) {
            super(name, age);
            this.grade = grade;
        }
        
        study() {
            console.log(`${this.name} is studying`);
        }
    }
    
    let student = new Student("Bob", 20, "A");
    student.greet(); // "Hello, I'm Bob"
    student.study(); // "Bob is studying"
  • super() 调用父类构造函数。


11. Promise 和异步操作

原理解析

11.1 Promise 的构造

  • Promise 是用于处理异步操作的一种机制,可以简化回调函数的使用,避免回调地狱

    javascript 复制代码
    let promise = new Promise((resolve, reject) => {
        let success = true;
        if (success) {
            resolve("Operation successful");
        } else {
            reject("Operation failed");
        }
    });
    
    promise.then((message) => {
        console.log(message); // "Operation successful"
    }).catch((error) => {
        console.log(error); // "Operation failed"
    });

11.2 Promise 的链式调用

  • then() 返回一个新的 Promise,因此可以链式调用多个异步操作:

    javascript 复制代码
    let promise = new Promise((resolve, reject) => resolve(10));
    
    promise.then(value => {
        return value * 2;
    }).then(value => {
        console.log(value); // 20
    });

12. 模块化(Modules, import/export

原理解析

12.1 导出(export

  • 使用 export 将函数、变量或类导出,使其可以在其他文件中使用:

    javascript 复制代码
    // math.js
    export const pi = 3.14;
    export function add(a, b) {
        return a + b;
    }

12.2 导入(import

  • 使用 import 从其他模块导入:

    javascript 复制代码
    // main.js
    import { pi, add } from './math.js';
    console.log(pi); // 3.14
    console.log(add(2, 3)); // 5

13. Symbol 类型

原理解析

13.1 唯一性

  • Symbol 是一个 唯一的原始数据类型 ,每个 Symbol 值都是唯一的。

    javascript 复制代码
    let sym1 = Symbol("desc");
    let sym2 = Symbol("desc");
    console.log(sym1 === sym2); // false

13.2 用作对象的私有属性

  • Symbol 可以用于创建私有对象属性,防止外部访问:

    javascript 复制代码
    const secret = Symbol("secret");
    let obj = {
        [secret]: "hidden"
    };
    console.log(obj[secret]); // "hidden"

    j

相关推荐
祈澈菇凉1 小时前
Webpack的基本功能有哪些
前端·javascript·vue.js
life_time_1 小时前
C语言(22)
c语言·开发语言
Minner-Scrapy2 小时前
DApp 开发入门指南
开发语言·python·web app
记得早睡~2 小时前
leetcode150-逆波兰表达式求值
javascript·算法·leetcode
孤雪心殇2 小时前
简单易懂,解析Go语言中的Map
开发语言·数据结构·后端·golang·go
庸俗今天不摸鱼2 小时前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
菠菠萝宝2 小时前
【Java八股文】10-数据结构与算法面试篇
java·开发语言·面试·红黑树·跳表·排序·lru
奔跑吧邓邓子2 小时前
【Python爬虫(36)】深挖多进程爬虫性能优化:从通信到负载均衡
开发语言·爬虫·python·性能优化·负载均衡·多进程
不会Hello World的小苗2 小时前
Java——链表(LinkedList)
java·开发语言·链表