ES6

1. 箭头函数

  • 更简洁的语法:箭头函数可以减少冗余的代码,使函数表达式更加简洁。

  • 没有自己的 this 值:箭头函数没有自己的 this 值,它会继承外层函数的 this 值。这在处理嵌套函数时特别有用,避免了传统函数中 this 上下文丢失的问题。

  • 不能用作构造函数:箭头函数不能使用 new 关键字创建对象实例,因为它们没有自己的 this。

  • 没有 arguments 对象:箭头函数也没有自己的 arguments 对象,但可以使用剩余参数 …args 来代替。

    // 箭头函数
    const f = v => v;
    // 等同于
    const f = function (v) {
        return v;
    };
    

2. 模板字符串

    // 模板字符串
    const foo = `hello
    world`;
    // 等同于
    const foo = "hello\nworld";
    // 字符串中可以包含反引号

    const bar = `hello
    \`world`;
    // 等同于           
    const bar = "hello\n`world";

    // 模板字符串中嵌入变量
    const name = "runoob";
    const foo = `hello, ${name}`;
    // 等同于
    const foo = "hello, " + name;

    // 模板字符串中可以调用函数
    const foo = `hello ${functionBar()}`;
    // 模板字符串中可以调用对象的方法
    const foo = `hello ${objectBar.methodBar()}`;

3. 解构赋值

    // 数组解构 
    const [a, b, c] = [1, 2, 3];

    // 剩余元素
    const numbers = [1, 2, 3, 4, 5];
    const [first, second, ...rest] = numbers;
    console.log(first); // 输出: 1
    console.log(second); // 输出: 2
    console.log(rest);   // 输出: [3, 4, 5]

    // 对象解构
    const { foo, bar } = { foo: "aaa", bar: "bbb" };

    // 重命名变量
    const person = {
        firstName: 'Alice',
        lastName: 'Johnson',
        age: 30
    };

    const { firstName: fName, age: personAge } = person;
    console.log(fName);      // 输出: 'Alice'
    console.log(personAge);  // 输出: 30

    // 函数参数解构
    function add([x, y]) {
        return x + y;
    }
    // 函数返回值解构
    function example() {
        return {
            foo: "aaa",
            bar: "bbb"
        };
    }
    const { foo, bar } = example();

    // 嵌套解构
    const nestedObj = {
        outer: {
            inner: {
            value: 42
            }
        }
     };

    const { outer: { inner: { value } } } = nestedObj;
    console.log(value); 

4. Promise

用于处理异步操作的一种方式,解决了回调地狱(Callback Hell)问题,使异步编程变得更加直观和易读。

Promise 是一种表示异步操作结果的对象,它可以有三种状态:

  • Pending(待定):初始状态,表示异步操作正在进行中。
  • Fulfilled(已完成):表示异步操作成功完成,并且返回了结果。
  • Rejected(已拒绝):表示异步操作失败,通常会返回一个错误原因。

使用 Promise 可以更好地组织和控制异步代码流程,避免了回调地狱和层层嵌套的问题。

// 创建一个 Promise
const promise = new Promise((resolve, reject) => {
  // 异步操作,可以是网络请求、文件读取等
  setTimeout(() => {
    const success = true; // 假设操作成功
    if (success) {
      resolve("Operation successful");
    } else {
      reject("Operation failed");
    }
  }, 1000);
});

// 处理 Promise 结果
promise.then(result => {
  console.log(result); // 输出: "Operation successful"
}).catch(error => {
  console.error(error); // 输出: "Operation failed"
});

ES2017

1. async/await

async 函数是 Generator 函数的语法糖,它使得异步操作变得更加方便。

async function fetchData1() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Data 1 fetched");
    }, 1000);
  });
}

async function main() {
  try {
    console.log("Before fetchData1");
    const data1 = await fetchData1();
    console.log("After fetchData1");

    console.log(data1);
  } catch (error) {
    console.error(error);
  }
}

console.log("Before calling main");
main();
console.log("After calling main");

ES2020

1. 空值合并运算符 ??

空值合并运算符 ?? 用于处理变量为 nullundefined 时的情况,它会返回第一个非空的操作数。这与逻辑或运算符 || 不同,?? 只在左操作数为 nullundefined 时才会返回右操作数。

示例:

const value1 = null;
const value2 = "Hello";

const result = value1 ?? value2;
console.log(result); // 输出: "Hello"

2. 可选链运算符 ?.

可选链运算符 ?. 用于访问对象的属性或调用方法,但在访问的路径上遇到 nullundefined 时会立即返回 undefined,而不会抛出错误。这在访问可能不存在的属性或方法时非常有用。

示例:

const person = {
  name: "John",
  address: {
    city: "New York",
  },
};

const cityName = person?.address?.city;
console.log(cityName); // 输出: "New York"

const unknown = person?.unknownProperty?.nestedProperty;
console.log(unknown); // 输出: undefined

这里,person?.address?.cityperson 对象上安全地访问了 addresscity 属性,而 person?.unknownProperty?.nestedProperty 在路径中遇到未定义的属性时返回 undefined