【前端之ES6】

1、ECMA6Script的介绍

ECMAScript 6官网

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,它的目标是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

ES6带来的 箭头函数、模板字符串、let和const关键字、解构、默认参数值、模块系统大量的新特性,使得JavaScript代码更为简洁,功能更加强大,大大提升了JavaScript的开发体验。VUE3中就大量使用了ES6的语法。

2、let 和 var (主要) 差别

① let 不能重复声明,var 可以

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>let和var</title>
  <script>
    var b = 2;
    var b = 3;//可以重复声明

    let a = 1;
    let a = 6;//报错:Identifier 'a' has already been declared

  </script>
</head>

<body></body>

</html>

② let声明的变量只在它所在的代码块有效,var声明的变量全局范围内都有效

for循环中推荐使用 let

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>let和var</title>
  <script>
    {
      let a = 1;
      var b = 2;
    }
    console.log(b); // 2
    console.log(a); // 报错: a is not defined   花括号外面无法访问

  </script>
</head>

<body></body>

</html>

③ 不存在变量提升(先声明,再使用)

let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>let和var</title>
  <script>
    console.log(test);  //可以 但是值为undefined
    var test = "test";

    console.log(test1); //报错:Cannot access 'test1' before initialization  
    let test1 = "test1";
  </script>
</head>

<body></body>

</html>

④ 不会成为window的属性

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>let和var</title>
  <script>
      var a = 100;
      console.log(window.a); //100

      let bb = 200;
      console.log(window.bb); //undefined
  </script>
</head>

<body></body>

</html>

3、const

const 和 let 类似,只是 const 定义的变量不能修改,类似final

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>const</title>
  <script>
    //1.常量声明必须有初始化值
    const v       //报错:Missing initializer in const declaration(没有赋初始值)
//-------------------------------------------------------------------------------
    //2.常量值不可以改动
    let a = 1
    a = 2         // 可以改变
    const b = 2
    b = 3         //报错:Assignment to constant variable(赋值给常量变量)
//-------------------------------------------------------------------------------
    //3.声明场景语法,建议变量名大写区分
    const PI = 3.1415926;
//-------------------------------------------------------------------------------
    //4.和let一样,块儿作用域
    {
      const A = "summer";
      console.log(A);
    }
     console.log(A); // 报错;A is not defined
//-------------------------------------------------------------------------------
    //5.对应数组和对象元素修改,不算常量修改,修改值,不修改地址
    const TEAM = ["刘德华", "张学友", "郭富城"];
    TEAM.push("黎明"); //可以
    TEAM = []; // 报错: Assignment to constant variable(赋值给常量变量) 不能指向新的数组(地址值不能改变)
    console.log(TEAM);
  </script>
</head>

<body></body>

</html>

4、模板字符串

模板字符串(template string)是增强版的字符串,用 反引号 ` 标识

  1. 字符串中可以出现换行符
  2. 可以使用 ${xxx} 形式输出变量和拼接变量
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>const</title>
  <script>
    // 1.普通字符串拼接
    let name = "中华";
    let infoStr = name + "人民共和国";
    console.log(infoStr);
    //---------------------------------------------------------------
    // 2.模板字符串拼接
    let infoStr2 = `${name}小当家`;
    console.log(infoStr2);
    //---------------------------------------------------------------
    // 3.多行普通字符串
    let ulStr = "<ul>" +
      "<li>JAVA</li>" +
      "<li>html</li>" +
      "<li>VUE</li>" +
      "</ul>";
    console.log(ulStr);
    //---------------------------------------------------------------
    // 4.多行模板字符串
    let ulStr2 =
      `<ul>
                  <li>JAVA</li>
                  <li>html</li>
                  <li>VUE</li>
                </ul>`;

    console.log(ulStr2);


  </script>
</head>

<body></body>

</html>

执行结果:
在这里插入图片描述

5、es6的解构表达式

ES6 的解构赋值是一种方便的语法,可以快速将数组或对象中的值拆分并赋值给变量。解构赋值的语法使用花括号 {} 表示对象方括号 [] 表示数组

Ⅰ、数组解构赋值

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的解构表达式</title>
  <script>
    //可以通过数组解构将数组中的值赋值给变量
    //新增变量名任意合法即可,本质是按照顺序进行初始化变量的值
    let [aa, bbb, c] = [1, 2, 3];
    console.log(aa); // 1
    console.log(bbb); // 2
    console.log(c); // 3

    //该语句将数组 [1, 2, 3] 中的第一个值赋值给 aaa 变量,第二个值赋值给 bbbb 变量,第三个值赋值给 cc 变量。
    //可以使用默认值为变量提供备选值,在数组中缺失对应位置的值时使用该默认值。例如:
    let [aaa, bbbb, cc, d = 4] = [1, 2, 3];
    console.log(d); // 4

  </script>
</head>

<body></body>

</html>

Ⅱ、对象解构赋值

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的解构表达式</title>
  <script>
    // 可以通过对象解构将对象中的值赋值给变量,语法为:
    let { a, b } = { a: 1, b: 2 };
    //新增变量名必须和属性名相同,本质是初始化变量的值为对象中同名属性的值
    //等价于 let a = 对象.a  let b = 对象.b
    console.log(a); // 1
    console.log(b); // 2

    //该语句将对象 {a: 1, b: 2} 中的 a 属性值赋值给 a 变量,b 属性值赋值给 b 变量。
    //可以为标识符分配不同的变量名称,使用 : 操作符指定新的变量名。例如:
    let { a: x, b: y } = { a: 66, b: 88 };
    console.log(x); // 66
    console.log(y); // 88
  </script>
</head>

<body></body>

</html>

Ⅲ、函数参数解构赋值

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的解构表达式</title>
  <script>
    //解构赋值也可以用于函数参数。例如:
    function add([x, y]) {
      return x + y;
    }

    console.log(add([1, 2]))    // 3
  </script>
</head>

<body></body>

</html>

6、es6的箭头函数

ES6 允许使用“箭头” 义函数。语法类似Java中的Lambda表达式

① 箭头函数声明

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的箭头函数</title>
  <script>
    //函数声明:
    //普通函数
    let fun1 = function () { }
    //箭头函数,此处不需要书写function关键字
    let fun2 = () => { } 
    //单参数可以省略(),多参数无参数不可以!
    let fun3 = x => { }
    //只有一行方法体可以省略{};
    let fun4 = x => console.log(x) 
    //当函数体只有一句返回值时,可以省略{}和 return 语句
    let fun5 = x => x + 1 
  </script>
</head>

<body></body>

</html>

② 箭头函数this关键字

箭头函数没有自己的this,箭头函数中的this是外层上下文环境中的this

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的箭头函数</title>
  <script>
    //箭头函数没有自己的this,箭头函数中的this是外层上下文环境中的this
    console.log(this)
    console.log("-----------------------------------------")

    let user = {
      age: 18,
      showInfo: function () {
        console.log(this)
        console.log(this.age)
      },
      viewInfo: () => {//此this的外层是user对象,user对象上下文环境中的this就是Window对象,Window对象无age属性
        console.log(this)
        console.log(this.age)
      }
    }

    user.showInfo();
    console.log("-----------------------------------------")
    user.viewInfo();

  </script>
</head>

<body></body>

</html>

在这里插入图片描述

③ 箭头函数this牛刀小试

练习:点击图片,两秒后变换颜色

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的箭头函数this练习</title>
  <style>
    #xdd {
      display: inline-block;
      width: 200px;
      height: 200px;
      background-color: red;
    }

    #tmd {
      display: inline-block;
      width: 200px;
      height: 200px;
      background-color: lightblue;
    }
  </style>
</head>

<body>
  <div id="xdd"><a style="font-size: 26px;">不使用箭头函数</a></div><br>
  <div id="tmd"><a style="font-size: 26px;">使用箭头函数</a></div>
  <script>
    let xdd = document.getElementById("xdd");
    let tmd = document.getElementById("tmd");
    // 方案1  
    xdd.onclick = function () {
      console.log(this)  // <div id="xdd"><a style="font-size: 26px;">不使用箭头函数</a></div><br>
      let _this = this;
      //开启定时器
      window.setTimeout(function () {
        console.log(this) //Window对象
        //点击后2秒变黄
        _this.style.backgroundColor = 'yellow';
      }, 2000);
    }


    // 方案2  使用箭头函数
    tmd.onclick = function () {
      console.log(this)  //    <div id="tmd"><a style="font-size: 26px;">使用箭头函数</a></div>
      //开启定时器
      window.setTimeout(() => {
        //使用setTimeout() 方法所在环境时的this对象
        console.log(this)//    <div id="tmd"><a style="font-size: 26px;">使用箭头函数</a></div>
        //变绿
        this.style.backgroundColor = 'pink';
      }, 2000);
    }
  </script>
</body>

</html>

演示结果:

ES6箭头函数中 this 关键字理解

④ rest和spread

rest 剩余的,解决剩余的参数接收问题,因为箭头函数中无法使用arguments,rest 是一种解决方案。 rest参数在一个参数列表中的最后一个,这也就无形之中要求一个参数列表中只能有一个rest参数

rest 剩余:是把 ...args 用在了参数列表作为形参使用的;

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的箭头函数rest</title>

  <script>
    //rest 剩余的,解决剩余的参数接收问题,因为箭头函数中无法使用arguments,rest 是一种解决方案
    // rest参数在一个参数列表中的最后一个只,这也就无形之中要求一个参数列表中只能有一个rest参数
    
    //let fun5 =  (...args,...args2) =>{} // 这里报错

    let fun3 = function (a, b, c, ...args) {
      console.log(a, b, c)//  1 2 3
      console.log(args)   //  (6) [4, 5, 6, 7, 8, 9]
    }
    let fun4 = (...args) => {
      console.log(args)   //(5) [12, 23, 34, 45, 56]
    }
    fun3(1, 2, 3, 4, 5, 6, 7, 8, 9)
    fun4(12, 23, 34, 45, 56)
  </script>
</head>

<body>
</body>

</html>

spread 展开:是把 ...args 放在方法调用时作为实参使用的;
1、方法调用使用
2、快速合并数组
3、快速合并对象

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6的箭头函数 spread</title>

  <script>

    //-------------------------1、方法调用使用
    let arr = [1, 2, 3]
    //let arrSpread = ...arr;// 这样不可以,...arr必须在调用方法时作为实参使用
    let fun1 = (a, b, c) => {
      console.log(a, b, c)
    }

    fun1(arr)//(3) [1, 2, 3] undefined undefined   会把arr整体赋值给a,b和c均为 undefined
    fun1(...arr)//1 2 3
    //-------------------------2、快速合并数组
    let a = [1, 2, 3]
    let b = [3, 4]
    let c = [5, 6]
    let d = [...a, ...b, ...c]
    console.log(d)//(7) [1, 2, 3, 3, 4, 5, 6]
    //-------------------------3、快速合并对象
    let p1 = { name: "张三" }
    let p2 = { age: 10 }
    let p3 = { gender: "boy" }
    let person = { ...p1, ...p2, ...p3 }
    console.log(person)//{name: '张三', age: 10, gender: 'boy'}

  </script>
</head>

<body>
</body>

</html>

7、es6的对象创建和拷贝

ES6中新增了对象创建的语法糖,支持了class extends constructor等关键字,让ES6的语法和面向对象的语法更加接近

① 对象创建的语法糖

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>es6对象创建的语法糖</title>
  <script>
    class Person {
      // 属性
      #n;
      age;
      get name() {
        return this.n;
      }
      set name(n) {
        this.n = n;
      }
      // 实例方法
      eat(food) {
        console.log(this.age + "岁的" + this.n + "用筷子吃" + food)//10岁的小明用筷子吃火锅
      }
      // 静态方法
      static sum(a, b) {
        return a + b;
      }
      // 构造器
      constructor(name, age) {
        this.n = name;
        this.age = age;

      }
    }
    let person = new Person("张三", 10);
    // 访问对象属性
    // 调用对象方法
    console.log(person.name)//张三
    console.log(person.n)//张三
    person.name = "小明"
    console.log(person.age)//10
    person.eat("火锅")
    console.log(Person.sum(1, 2))//3

    class Student extends Person {
      grade;
      score;
      study() {

      }
      constructor(name, age) {
        super(name, age);
      }
    }

    let stu = new Student("学生小李", 18);//18岁的学生小李用筷子吃面条
    stu.eat("面条")
  </script>
</head>

<body>
</body>

</html>

② 对象的深拷贝和浅拷贝

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>对象的深拷贝和浅拷贝</title>
  <script>
    let arr = ['java', 'c', 'python']
    let person = {
      name: '张三',
      language: arr
    }
    // 浅拷贝,person2和person指向相同的内存
    let person2 = person;
    person2.name = "小黑"
    console.log(person.name)//小黑
    console.log(person2.name)//小黑
    console.log("==============================================")
    let arr2 = ['java', 'c', 'python']
    let person3 = {
      name: '李四',
      language: arr2
    }
    // 深拷贝,通过JSON和字符串的转换形成一个新的对象
    let person4 = JSON.parse(JSON.stringify(person3))
    person4.name = "小白"
    console.log(person3.name)//李四
    console.log(person4.name) //小白
  </script>
</head>

<body>
</body>

</html>

8、es6的模块化处理

模块化是一种组织管理前端代码的方式,将代码拆分成小的模块单元;提高代码可维护性、可复用性、可扩展性

  • ES6模块化的暴露导入方式
    1. 分别导出
    2. 统一导出
    3. 默认导出
  • ES6中无论以何种方式导出,导出的都是一个对象,导出的内容都可以理解为是向这个对象中添加属性或者方法

① 分别导出

模块想对外导出,添加export关键字

在这里插入图片描述

Ⅰ、module.js 向外分别暴露成员

//1.分别暴露
// 模块想对外导出,添加export关键字即可!
// 导出一个变量
export const PI = 3.14;
const PI2 = 5.68;

// 导出一个函数
export function sum(a, b) {
  return a + b;
}

// 导出一个类
export class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
  }
}

Ⅱ、app.js 导入module.js中的成员

/* 
    *代表module.js中的所有成员
    m1代表所有成员所属的对象
*/
import * as m1 from "./module.js";
// 使用暴露的属性
console.log(m1.PI); //3.14
console.log(m1.PI2); //undefined       【module.js中没有对外暴露PI2,所以无法使用】
// 调用暴露的方法
let result = m1.sum(10, 20);
console.log(result); //Hello, my name is 张三, I'm 10 years old.
// 使用暴露的Person类
let person = new m1.Person("张三", 10);
person.sayHello();

Ⅲ、index.html作为程序启动的入口 导入 app.js
导入JS文件 添加type=‘module’ 属性,否则不支持ES6的模块化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title><!-- 导入JS文件 添加type='module' 属性,否则不支持ES6的模块化 -->
    <script src="./app.js" type="module" />
</head>

<body>

</body>

</html>

② 统一导出

Ⅰ、module.js 向外分别暴露成员

//2.统一暴露
// 模块想对外导出,export统一暴露想暴露的内容!
// 定义一个常量
const PI = 3.14;
// 定义一个函数
function sum(a, b) {
  return a + b;
}
// 定义一个类
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
  }
}
// 统一对外导出(暴露)
export { PI, sum, Person };

Ⅱ、app.js 导入module.js中的成员

/* 
    {}中导入要使用的来自于module.js中的成员
    {}中导入的名称要和module.js中导出的一致,也可以在此处起别名
    {}中如果定义了别名,那么在当前模块中就只能使用别名
    {}中导入成员的顺序可以不是暴露的顺序
    一个模块中可以同时有多个import
    多个import可以导入多个不同的模块,也可以是同一个模块
*/
//import {PI ,Person ,sum }  from './module.js'
//import {PI as pi,Person as People,sum as add}  from './module.js'
import {
  PI,
  Person,
  sum,
  PI as pi,
  Person as People,
  sum as add,
} from "./module.js";
// 使用暴露的属性
console.log(PI); //3.14
console.log(pi); //3.14
// 调用暴露的方法
let result1 = sum(10, 20);
console.log(result1); //30
let result2 = add(10, 20);
console.log(result2); //30
// 使用暴露的Person类
let person1 = new Person("张三", 10);
person1.sayHello(); //Hello, my name is 张三, I'm 10 years old.
let person2 = new People("李四", 11);
person2.sayHello(); //Hello, my name is 李四, I'm 11 years old.


Ⅲ、index.html作为程序启动的入口 导入 app.js
导入JS文件 添加type=‘module’ 属性,否则不支持ES6的模块化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title><!-- 导入JS文件 添加type='module' 属性,否则不支持ES6的模块化 -->
    <script src="./app.js" type="module" />
</head>

<body>

</body>

</html>

③ 默认导出 export default

Ⅰ、module.js 向外分别暴露成员

// 3默认和混合暴露
/* 
    默认暴露语法  export default sum
    默认暴露相当于是在暴露的对象中增加了一个名字为default的属性
    三种暴露方式可以在一个module中混合使用

*/
export const PI = 3.14
// 导出一个函数
function sum(a, b) {
  return a + b;
}
// 导出一个类
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
  }
}

// 导出默认
export default sum
// 统一导出
export {
   Person
}

Ⅱ、app.js 导入module.js中的成员

/* 
    *代表module.js中的所有成员
    m1代表所有成员所属的对象
*/
import * as m1 from "./module.js";
import { default as add } from "./module.js"; // 用的少
import add2 from "./module.js"; // 等效于 import {default as add2} from './module.js'

// 调用暴露的方法
let result = m1.default(10, 20);
console.log(result);//30
let result2 = add(10, 20);
console.log(result2);//30
let result3 = add2(10, 20);
console.log(result3);//30

// 引入其他方式暴露的内容
import { PI, Person } from "./module.js";
// 使用暴露的Person类
let person = new Person("张三", 10);
person.sayHello();//Hello, my name is 张三, I'm 10 years old.
// 使用暴露的属性
console.log(PI);//3.14

Ⅲ、index.html作为程序启动的入口 导入 app.js
导入JS文件 添加type=‘module’ 属性,否则不支持ES6的模块化

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 导入JS文件 添加type='module' 属性,否则不支持ES6的模块化 -->
    <script src="./app.js" type="module" />
</head>

<body>

</body>

</html>
  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值