第Ⅰ章-VI 熟练掌握ES6新特性以及盲点

第Ⅰ章-Ⅰ 了解Vue3 创建一个Vue3项目
第Ⅰ章-Ⅱ Vue3自定义创建项目 项目文件详解
第Ⅰ章-III Vite 创建vue3 项目
第Ⅰ章-IV npm yarn pnpm 包管理器
第Ⅰ章-V package.json文件详解

简介

ECMAScript6(简称ES6)是Javascript语言的第六个版本,2015年发布,也称为ESMAScript2015或ES2015。它引入了大量的新特性,新语法和新功能。极大的丰富了JavaScript语言的能力,使其更适合现代化开发。

主要特性

1.块级作用域和 let、const

ES6 引入了 let 和 const 关键字,用于创建具有块级作用域的变量。

  • let:用于定义一个可变变量,其作用域受限于所在的块
if (true) {
    let x = 42;
    console.log(x); // 输出 42
}
console.log(x); // 报错:x is not defined
  • const:用于定义一个不可变变量,其作用域也受限于所在的块
const PI = 3.14;
console.log(PI);

// PI = 3.1415; // 报错:Assignment to constant variable.

这里 PI 在定义后不可修改。

提示:const不可重新赋值,对象的属性可以修改。由于 const 定义的变量不会改变,JavaScript 引擎可以对这些变量进行优化,这可以在某些情况下提高代码性能。

const person={name:"Tom",age:31};
person.age=30;
console.log(person);//输出{name:"Tom",age:30}

2.箭头函数

ES6引入了箭头函数,一种简洁的函数定义方式。

const add=(a,b)=>a+b;
console.log(add(1,2));//输出3
  • 简洁性:省略了function关键字,并且单行返回值时可以省略 return 语句。
  • this 绑定:箭头函数中的 this 会继承自外层作用域,而不会创建新的 this 绑定。

提示:如果箭头函数外部没有包含函数就会绑定到全局作用域。普通函数没有绑定到对象上没有自己的this,会指向全局对象

3.模板字符串

用于构建更易读的字符串。

const name = "Alice";
const greeting = `Hello, ${name}!`;
console.log(greeting); // 输出 "Hello, Alice!"

模板字符串使用反引号 ` 括起,并支持内嵌表达式 ${}

4.解构赋值

解构赋值是一种方便的语法,可以从数组或对象中提取值。

  • 数组
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 输出 1 2 3
  • 对象解构
const person = { name: "Alice", age: 30 };
const { name, age } = person;
console.log(name, age); // 输出 "Alice" 30

5.类

ES6 引入了 class 关键字,为 JavaScript 提供了面向对象的语法。

// 定义一个 ES6 类
class Person {
  // 构造函数,在实例化时会被调用
  constructor(name, age) {
    this.name = name; // 类的属性
    this.age = age; // 类的属性
  }

  // 类的方法,打印名字和年龄
  sayHello() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
}

// 实例化类
const john = new Person('John', 30);

// 调用类的方法
john.sayHello(); // 输出:Hello, my name is John and I'm 30 years old.
  • class Person { … }: 这是 ES6 中定义类的语法。Person 是类的名称。
  • constructor(name, age) { … }: 这是类的构造函数,用于初始化类的实例。name 和 age 是构造函数的参数,用来设置类的属性。
  • this.name 和 this.age: 这是类的属性。通过 this 关键字,表示当前实例的属性。
  • sayHello() { … }: 这是类的方法。它定义了一个名为 sayHello 的方法,用于打印实例的名字和年龄。
  • const john = new Person(‘John’, 30);: 这是创建类的实例,使用 new 关键字后跟类名,并传递构造函数所需的参数。
  • john.sayHello();: 这是调用类的方法,使用实例名后跟方法名,并加上括号传递所需的参数。

6.模块化

可以使用 import 和 export 来组织代码

  • 导出模块
export function greet(name) {
    return `Hello, ${name}!`;
}
  • 导入模块
import { greet } from './utils.js';
console.log(greet("Alice")); // 输出 "Hello, Alice!"

在 JavaScript 中,模块系统需要明确指定哪些成员是可以从模块中导出的。通过 export 关键字,我们可以将需要导出的成员(变量、函数、类等)标记为可供其他模块使用。然后,通过 import 关键字,我们可以在其他模块中导入需要的成员,以便在当前模块中使用。

提示:如果导入的模块是 JavaScript 文件(.js)、JSON 文件(.json)或 Node.js 内置模块等,可以省略文件扩展名。因为在这些情况下,JavaScript 引擎会根据导入的模块名自动查找对应的文件。

7.Promise

用于简化异步操作。

const fetchData = () => new Promise((resolve, reject) => {
    setTimeout(() => resolve("Data fetched!"), 1000);
});

fetchData().then(data => console.log(data)); // 1 秒后输出 "Data fetched!"

Promise 提供了 then 和 catch 方法来处理异步操作的结果和错误。

async await

// 异步函数,返回一个 Promise 对象
async function fetchData() {
  // 模拟异步操作,比如向服务器请求数据
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
}

// 使用 async/await 处理异步操作
async function getData() {
  try {
    // 使用 await 等待异步函数 fetchData 的完成,并获取返回值
    const data = await fetchData();
    // 在异步操作完成后执行下面的代码
    console.log(data); // 输出: Data fetched successfully
  } catch (error) {
    // 捕获异步操作中的错误
    console.error('Error fetching data:', error);
  }
}

// 调用异步函数
getData();
  • async function fetchData():定义了一个异步函数 fetchData(),该函数内部返回一个 Promise 对象。
  • return new Promise(resolve => { … }):在异步函数内部,模拟了一个异步操作,通过 setTimeout 模拟了一段延迟执行的操作,并在操作完成后调用 resolve() 方法,将 Promise 置为成功状态,并传递数据给 resolve()。
  • async function getData():定义了另一个异步函数 getData(),该函数使用了 async/await。
  • const data = await fetchData();:在 getData() 函数中使用 await 关键字等待 fetchData() 函数的完成,并获取其返回值。await 关键字可以暂停异步函数的执行,直到被等待的 Promise 对象状态变为 resolved(成功)或 rejected(失败)。
  • try { … } catch (error) { … }:使用了 try…catch 块来捕获异步操作中可能抛出的错误。如果异步操作成功,则会执行 try 代码块中的代码;如果异步操作失败(抛出异常),则会执行 catch 代码块中的代码。
  • console.log(data):在异步操作成功后,输出获取到的数据。
  • getData():调用 getData() 函数,触发异步操作。

async/await 让异步操作的代码看起来更加清晰和直观,避免了回调地狱,并使得异步代码的错误处理更加方便。

8.迭代器与生成器

迭代器和生成器是 JavaScript 中用于处理集合的强大工具。它们可以让你更灵活地遍历和操作数据集合,以及在需要时延迟生成值。

迭代器

const arr = [1, 2, 3];
const iterator = arr[Symbol.iterator]();

console.log(iterator.next()); // 输出 { value: 1, done: false }

生成器

function* count() {
    yield 1;
    yield 2;
    yield 3;
}

const counter = count();
console.log(counter.next().value); // 输出 1

其他特性

默认参数

为函数参数设置默认值

function greet(name = "World") {
    console.log(`Hello, ${name}!`);
}

扩展运算符

用于扩展数组或对象

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // 输出 [1, 2, 3, 4, 5]

符号(Symbols)

一种唯一的标识符类型

const sym1 = Symbol("desc");
const sym2 = Symbol("desc");
console.log(sym1 === sym2); // 输出 false
避免命名冲突

Symbols 可以用于为对象添加独特的属性,从而避免与其他属性发生命名冲突:

const symKey = Symbol("uniqueKey");

const obj = {
    [symKey]: "value",
    normalKey: "another value"
};

console.log(obj[symKey]); // 输出 "value"
console.log(obj.normalKey); // 输出 "another value"

在这个示例中,我们通过 Symbol 添加了一个独特的属性 symKey,避免了与其他属性发生冲突。

定义私有属性

由于 Symbols 是唯一且不可枚举的(不会出现在 for…in 或 Object.keys() 等方法中),你可以使用 Symbols 来定义私有属性:

const symAge = Symbol("age");

class Person {
    constructor(name, age) {
        this.name = name;
        this[symAge] = age;
    }

    getAge() {
        return this[symAge];
    }

const p = new Person("Alice", 30);
console.log(p.getAge()); // 输出 30

for (let key in p) {
    console.log(key); // 只输出 "name"
}
}

symAge 属性通过 Symbol 添加,不会出现在 for…in 等枚举中,因此可以用于定义私有属性。

元编程

Symbols 提供了几个内置的 Symbol(如 Symbol.iterator、Symbol.toStringTag 等),可以用于元编程:
Symbol.iterator:可以定义对象的迭代器,使其可以用于 for…of 循环:

const range = {
    start: 1,
    end: 3,
    [Symbol.iterator]() {
        let current = this.start;
        return {
            next: () => ({
                value: current,
                done: current++ > this.end
            })
        };
    }
};

for (let num of range) {
    console.log(num); // 输出 1, 2, 3
}
Symbol.toStringTag

可以自定义对象的 toString() 行为:

class MyClass {
    get [Symbol.toStringTag]() {
        return "MyCustomClass";
    }
}

const obj = new MyClass();
console.log(obj.toString()); // 输出 "[object MyCustomClass]"
扩展方法

Symbols 还可以用于为对象定义不可枚举的扩展方法

const symMethod = Symbol("customMethod");

const obj = {
    [symMethod]: function () {
        console.log("Custom method called.");
    }
};

obj[symMethod](); // 调用自定义方法

for (let key in obj) {
    console.log(key); // 不会输出 symMethod
}

这里定义了一个使用 Symbol 作为键的扩展方法,并确保它不可枚举。

合理利用 Symbols,你可以更好地组织和管理对象属性,编写更简洁、健壮的代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值