ES6 & ESNext 规范及编译工具简介

ES6 & ESNext 规范及编译工具简介

  • 1、历史简介
  • 2、变量定义新形式(let、const)
    • [2.1 let](#2.1 let)
    • [2.2 const](#2.2 const)
    • [2.3 实际开发中的使用](#2.3 实际开发中的使用)
  • 3、解构语法
    • [3.1 数组解构](#3.1 数组解构)
    • [3.2 对象解构](#3.2 对象解构)
    • [3.3 嵌套解构](#3.3 嵌套解构)
    • [3.4 默认值](#3.4 默认值)
  • 4、模板字符串
  • [5、 箭头函数](#5、 箭头函数)
  • 6、ES6新增的数组方法
  • 7、Set和Map
    • [7.1 Set](#7.1 Set)
    • [7.2 Map](#7.2 Map)
  • [8、面向对象编程------class 语法](#8、面向对象编程——class 语法)
    • [8.1 类、构造函数](#8.1 类、构造函数)
    • [8.2 继承](#8.2 继承)
    • [8.3 静态方法和属性](#8.3 静态方法和属性)
    • [8.4 getter 和 setter](#8.4 getter 和 setter)
  • [9、生成器 generator](#9、生成器 generator)
  • [10、异步处理------callback、Promise、async & await](#10、异步处理——callback、Promise、async & await)

1、历史简介

ECMAScript:一种标准(ECMA-262)

JavaScript:一种语言

ES5:2011发布,第五个版本

ES6:2015发布的,第六个版本,大型变动 break change

ESNext:符合现在主流ES的预案,有几个阶段(大于1的就是属于ESNext)

阶段:

Stage 0:开工

Stage 1:收录意见

Stage 2:草案

3:候选者(基本要准备发布)

4:定案

2、变量定义新形式(let、const)

Q: var 定义变量有什么问题?

  1. 变量提升
  2. 无法形成词法作用域
  3. 可以随意篡改变量值,重复声明

2.1 let

let 关键字用于声明一个块级作用域的局部变量,可以将 let 声明的变量重新赋值。let 声明的变量只在代码块内部有效。

javascript 复制代码
if (true) {
    let i = 1;
    console.log(i); // 输出 1
}
console.log(i); // 报错,i 未定义

console.log(a); // undefind(变量提升)
var a=2;

console.log(b); //报错,暂时性死区,let在下面定义了
let b=2

死区

javascript 复制代码
function bar(x=y,y=2){
    return [x,y]
}
bar()
//报错,y死区(运行时报错)
function bar(x=2,y=x){
    return [x,y]
}
bar()
//正常执行

不允许重复声明

javascript 复制代码
var a=2;
let a=1;
//报错

2.2 const

const 关键字用于声明一个块级作用域只读常量,一旦 const 声明了某个变量,就不能使用赋值语句改变它的值。常量必须在声明时进行初始化

javascript 复制代码
const PI = 3.1415926535;
PI = 3; // 报错,无法修改常量

const obj={}//具体引用的地址不能变
obj.a=1//不报错
obj=1//报错

ES5里没有块级作用域

javascript 复制代码
//ES6写法
if(true){
   function fn(){
   }
}
//ES5写法
if(true){
 var fn = function(){
   }
}

2.3 实际开发中的使用

  1. 示例一:循环中使用 let 声明变量避免问题
javascript 复制代码
for (let i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i); // 0, 1, 2, 3, 4
    }, 1000);
}

使用 let 声明的变量 i 有块级作用域,在每一次循环中都会重新定义并赋值,避免了使用 var 声明变量可能导致的变量共享问题。

  1. 示例二:使用 const 声明常量
javascript 复制代码
const PI = 3.1415926;
const URL = "https://www.example.com";

使用 const 声明常量可以防止被修改,保证代码的可靠性和稳定性。

  1. 示例三:使用 const 声明对象属性避免误修改
javascript 复制代码
const user = {
    name: "张三",
    age: 18,
    gender: "男"
};

user.name = "李四";
console.log(user); // { name: "李四", age: 18, gender: "男" }

Object.freeze(user);

user.age = 20;
console.log(user); // { name: "李四", age: 18, gender: "男" }

使用 const 声明对象属性可以避免误修改,同时使用 Object.freeze() 方法可以将对象冻结,防止意外修改对象属性。

总的来说,使用 let 或者 const 声明变量可以解决一些以往使用 var

变量定义存在的问题,例如变量作用域混乱,变量共享、变量易被修改等情况。使用 let 和 const

可以使代码更加健壮、可维护,提升开发效率和代码质量。

3、解构语法

定义:将数组或对象中的元素提取出来并赋值给变量

3.1 数组解构

javascript 复制代码
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3

在这个例子中,JavaScript 引擎背后发生的事情如下:

javascript 复制代码
const tempArray = [1, 2, 3];
const a = tempArray[0];
const b = tempArray[1];
const c = tempArray[2];
console.log(a, b, c); // 1 2 3
javascript 复制代码
let [a, ...rest] = [1, 2, 3];
console.log(a, rest); // 1 [2,3]

[x,y,,z]=[1,2,3,4]
console.log(x,y,z); // 1,2,4

3.2 对象解构

javascript 复制代码
const {firstname: first, lastname: last, ...rest} = { firstname: 'John', lastname: 'Doe' };
console.log(first, last); // John Doe

let obj={
  p:['Hello',
  {y:'World'}
  ]
}
let {
 p:[x,{y}]
}=obj
//x,y   Hello,World

3.3 嵌套解构

javascript 复制代码
const [a, [b, [c]]] = [1, [2, [3]]];
console.log(a, b, c); // 1 2 3

3.4 默认值

javascript 复制代码
const [a = 1, b = 2] = [];
console.log(a, b); // 1 2

let obj={a:1,b:2,c:3}
const {a=2}=obj
//a=obj.a?obj.a:2,obj的a存在,取obj.a,不存在,取默认值2
const {a:d=2}=obj
//另外取名字  d=obj.a?obj.a:2

4、模板字符串

javascript 复制代码
const name = "Tom";
const age = 20;
const str = `My name is ${name}, I'm ${age} years old.
I'm from China.`;
console.log(str);

5、 箭头函数

箭头函数与普通函数有哪些不同?

  1. this 指向,箭头函数不能定义构造器
  2. 不能 new
  3. 内部无 arguments 对象
  4. this 绑定方法失效,比如:call apply bind
javascript 复制代码
// 传统函数定义
function multiply(x, y) {
  return x * y;
}
// 箭头函数
const multiply = (x, y) => x * y;

function foo(){
   setTimeout(() => {
      console.log(`num`,this.num);//没有自己的this,这里的this是foo的this
    }, 1000);
}
var num =123
foo()//输出 num 123
//改变函数指向
foo.call({
num:456
})
foo()//输出 num 456



//看一个例子
function Timer(){
  this.s1=0;
  this.s2=0;
  //箭头函数
  setInterval(()=>this.s1++,1000);//外层函数的this,指向Timer,改变了Timer实例的s1
  //普通函数
  setInterval(function(){
    this.s2++;//function的this,没有改变Timer实例的s2
  },1000);
}
var timer =new Timer()
    setTimeout(() => {
      console.log('s1:',timer.s1)
    }, 3100);
    setTimeout(() => {
      console.log('s2:',timer.s2)
    }, 3100);
    //输出:
    //s1:3
    //s2:0

6、ES6新增的数组方法

ES6新增了一些数组方法,具体可以看 ES6 入门教程

Js的全部数组方法,可以看 数组方法总结+详解

如:

  • Array.flat()
    Array.flat() 方法创建一个新数组,其中所有子数组元素递归地连接到指定的深度。(打平数组深度)
javascript 复制代码
 const arr = [1, [2, [3, [4]]]];
console.log(arr.flat(1)); // [1, 2, [3, [4]]]
console.log(arr.flat(2)); // [1, 2, 3, [4]]
console.log(arr.flat(3)); // [1, 2, 3, 4]
console.log(arr.flat(4)); // [1, 2, 3, 4]
  • Array.includes()
    Array.includes() 方法判断一个数组是否包含某个指定的元素,根据情况,如果包含则返回 true ,否则返回 false
javascript 复制代码
const arr = [1, 2, 3, 4, 5];
console.log(arr.includes(3)); // true
console.log(arr.includes(6)); // false

Array.from()

Array.of()

Array.find()

Array.findIndex()

Array.includes()

Array.flat()

Array.flatMap()

Array.every()

Array.some()

Array.reduce()

Array.reduceRight()

Array.sort()

Array.reverse()

Array.fill()

Array.slice()

Array.splice()

Array.copyWithin()

Array.forEach()

Array.map()

Array.filter()

7、Set和Map

Set 和 Map 主要的应用场景在于 数据重组数据储存

Set 是一种叫做 集合 的数据结构,Map 是一种叫做 字典 的数据结构。

7.1 Set

  • ES6 新增的一种新的数据结构,类似于数组,成员唯一(内部元素没有重复的值)。且使用键对数据排序即顺序存储。
  • Set 本身是一种构造函数,用来生成 Set 数据结构。
  • Set 对象允许你储存任何类型的唯一值,无论是原始值或者是对象引用
javascript 复制代码
var s1=new Set();
var s2=new Set([1,2,3]);
//  重复元素在Set中会自动过滤(即重复元素不会被保留)
var s=new Set([1,2,3,3]);
s.add(4);  // set{1,2,3,4}
s.add(3); //set{1,2,3,4}
s.size();   //4
s.has(3);  //true

weakSet 和Set一样的用法,不过里面的值只能是Symbol或对象,垃圾回收不会考虑weakSet 和weakMap里的值,内部变量没有可达性

7.2 Map

Map是一组键值对的结构,用于解决以往不能用对象做为键的问题,具有极快的查找速度。(注:函数、对象、基本类型都可以作为键或值。)

javascript 复制代码
const m=new map(['Kris',21],['Bob',19],['Lily',25],['Jack',27]);
m.get('Kris');   //  21
m.get('Lily');   //  25

var mm=new Map( );	//初始化一个空的 map
mm.set('Pluto',23);	//添加新的key-value 值
mm.has('Pluto');   //true	是否存在key 'Pluto'
mm.get('Pluto');   	//23
mm.delete('Pluto');	//删除key   'Pluto '

一个key只能对应一个value,所以多次对一个key放入value,后面的值会把前面的值冲掉
const m=new Map([['Lily',100],['Bob',97]]);
m.get('Bob');  //97
m.set('Bob',88);  //对key放入新的value
m.get('Bob');  //88

8、面向对象编程------class 语法

JavaScript 的类最终也是一种函数,JavaScript 的 class 语法只是语法糖,使用 class 关键字创建的类会被编译成一个函数,因此其底层原理与函数有一些相似之处。

JavaScript原型继承实现继承的有哪些方式(详情可以看这篇博客

  • 原型链继承
  • 借用构造函数
  • 组合继承
  • 原型式继承
  • 寄生式继承
  • 寄生组合继承

Class 语法继承,最接近我们自己实现的那种继承方式?

  • 寄生组合继承

8.1 类、构造函数

ES6里的类

javascript 复制代码
class Point{
  constructor(x,y){
     this.x=x;
     this.y=y;
  }
  toString(){
     return '('+this.x+','+this.y+')'
  }
}
new Point()

等价于ES5

javascript 复制代码
var Point = /*#__PURE__*/ (function () {
  function Point(x, y) {
    this.x = x;
    this.y = y;
  }
  var _proto=Point.prototype;
  _proto.toString=function toString(){
     return '('+this.x+','+this.y+')'
  }
  return Point;
})();
new Point();

8.2 继承

在 JavaScript 中,继承是通过类的 prototype 属性实现的。在定义类时,可以使用 extends 关键字来继承其他的类:

javascript 复制代码
class Student extends Person {
    constructor(name, age, grade) {
        super(name, age);
        this.grade = grade;
    }
}

8.3 静态方法和属性

类中的静态方法和属性可以使用 static 关键字来定义,它们不是类实例的属性,而是类本身的属性和方法。

javascript 复制代码
class Person {
    static species = "human";

    static saySpecies() {
        console.log(`We are ${this.species}.`);
    }
}

8.4 getter 和 setter

在类中定义 getter 和 setter 方法可以让我们封装实例的内部数据属性,使得这些属性的读写行为更加的安全和合理。

javascript 复制代码
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    get name() {
        return this.name.toUpperCase();
    }

    set age(age) {
        if (age > 0 && age < 120) {
            this.age = age;
        } else {
            console.log("Invalid age value.");
        }
    }

    get age() {
        return this.age;
    }
}

在类的实现中,getter 和 setter 其实是被定义在构造函数的 prototype 属性上,从而可以被该类的所有实例对象访问。

9、生成器 generator

生成器为了解决什么问题?

解决了函数的不可中断性

生成器是可中断函数,yield 关键字暂时中断函数执行,在合适的实际从中断位置继续执行。

javascript 复制代码
function* generateSequence() {
  yield 1;
  yield 2;
  yield 3;
}

const sequence = generateSequence(); // 获取生成器实例
console.log(sequence.next().value); // 输出 1
console.log(sequence.next().value); // 输出 2
console.log(sequence.next().value); // 输出 3

10、异步处理------callback、Promise、async & await

这个部分可以看博客:3.1、前端异步编程(超详细手写实现Promise;实现all、race、allSettled、any;async/await的使用)

相关推荐
崔庆才丨静觅21 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼3 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax