ECMAScript

ECMAScrit 简介

  • ECMAEuropean Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为Ecma国际。
  • ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言
  • Ecma国际制定了许多标准,而ECMA-262只是其中的一个,所有标准列表查看
  • http://www.ecma-international.org/publications/standards/Standard.htm

ECMA-262 历史

  • ECMAEuropean Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信

    第 1 版 1997年 制定了语言的基本语法
    第 2 版 1998年 较小改动
    第 3 版 1999年 引入正则、异常处理、格式化输出等。IE 开始支持
    第 4 版 2007年 过于激进、未发布
    第 5 版 2009年 严格模式、JSON、扩展对象、数组、原型、字符串、日期方法
    第 6 版 2015年 模块化、面向对象语法、Promise、箭头函数、letconst、数组解构赋值等等
    第 7 版 2016年 幂运算符、数组扩展
    第 8 版 2017年 Async/await、字符串扩展
    第 9 版 2018年 对象解构赋值、正则扩展
    第 10 版 2019年 扩展对象、数组方法
    ES.next 动态指向下一个版本
  • 注:从ES6开始,每年发布一个版本,版本号比年份最后一位大 1

为什么要学习ES6

  • ES6的版本变动内容最多,具有里程碑意义
  • ES6加入许多新的语法特性,编程实现更简单、高效
  • ES6是前端发展趋势,就业必备技能

let 关键字

  • let关键字用来声明变量,使用let声明的变量有几个特点:

    • 不允许重复声明

      <!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></head><body></body><script>// 不允许重复声明let a = 10;// let a = "abc"; // 报错console.log(a); // 10</script>
      </html>
      
    • 块儿级作用域

      <!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></head><body></body><script>// 块儿级作用域 for if// var 是没有块级作用域的for (var i = 0; i < 10; i++) {}console.log(i); // 10if (true) {var f = "abc";}console.log(f); // abc// let 是有块级作用域的for (let index = 0; index < 10; index++) {}// console.log(index); // 报错 index is not definedif (true) {let n = false;}// console.log(n); // 报错 n is not defined</script>
      </html>
      
    • 不存在变量提升

      <!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></head><body></body><script>// var 的变量提升console.log(a); //undefinedvar a = 10;// let 不存在变量提升// console.log(n); // 报错 Cannot access 'n' before initializationlet n = false;</script>
      </html>
      
    • 不影响作用域链

      <!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></head><body></body><script>// var 不影响作用域链function fn() {var a = 10;function fn1() {var b = 10;console.log(a + b); // 20}function fn2() {var c = 20;// console.log(a + b + c); // 报错 b is not defined}fn1();fn2();}// fn();// let 也不影响作用域链function foo() {let a = 10;function fn1() {let b = 10;console.log(a + b); // 20}function fn2() {let c = 20;// console.log(a + b + c); // 报错 b is not defined}fn1();fn2();}foo();</script>
      </html>
      
  • 应用场景:以后声明变量使用let就对了

const 关键字

  • const关键字用来声明常量,const声明有以下特点

    • 声明必须赋初始值

      <!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></head><body></body><script>// const a; // 报错 Missing initializer in const declarationconst a = 10;console.log(a); // 10</script>
      </html>
      
    • 标识符一般为大写

    • 不允许重复声明

      <!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></head><body></body><script>const a = false;// const a = 10; // 报错 Identifier 'a' has already been declaredconsole.log(a); // false</script>
      </html>
      
    • 值不允许修改

      <!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></head><body></body><script>const a = false;// a = 10; // 报错 Assignment to constant variable.console.log(a);</script>
      </html>
      
    • 块儿级作用域

      <!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></head><body></body><script>for (let i = 0; i < 10; i++) {const a = 20;var b = 10; // var 定义的变量在for循环中是没有块级作用域的}// console.log(a); // 报错 a is not definedconsole.log(b); // 10if (true) {const foo = false;}console.log(foo); // 报错 foo is not defined// const 在 for 和 if 都是具有块级作用域的</script>
      </html>
      
  • 注意: 对象属性修改和数组元素变化不会触发const错误

<!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></head><body></body><script>// 对象属性改变不会触发 const 错误const obj = {name: "张三",age: 10,sayHi: function () {console.log(this.name + ":hi");},};obj.name = "王五";obj.sayHi(); // 王五:hiobj.weight = "50";console.log(obj); // 也不会报错// 数组元素改变也不会触发 const 错误const arr = [];arr.push(10, 20, 30);console.log(arr); // [10, 20, 30]</script>
</html>
  • 应用场景:声明对象类型使用const,非对象类型声明选择let

变量的解构赋值

  • 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></head><body></body><script>const arr = ["张学友", "刘德华", "黎明", "郭富城"];// 数组的解构赋值 => 根据数组的下标有顺序的进行赋值let [zhang, liu, li, guo] = arr;console.log(zhang, liu, li, guo); // 张学友 刘德华 黎明 郭富城</script>
    </html>
    
    • 对象的解构赋值
    <!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></head><body></body><script>// 对象的解构赋值const lin = {name: "林志颖",tags: ["车手", "歌手", "小旋风", "演员"],sayHi: function () {console.log("唱歌");},};// 对象的解构赋值是将对象中的各个属性取出来 变量名称必须与属性名称一致const { name, tags, sayHi } = lin;console.log(name, tags, sayHi); // 林志颖console.log(tags); // ['车手', '歌手', '小旋风', '演员']console.log(sayHi); // ƒ () {console.log("唱歌");}sayHi(); // 唱歌</script>
    </html>
    
    • 复杂解构
    <!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></head><body></body><script>let wangfei = {name: "王菲",age: 18,songs: ["红豆", "流年", "暧昧", "传奇"],history: [{ name: "窦唯" }, { name: "李亚鹏" }, { name: "谢霆锋" }],};const {name,age,// 数组的解构 => string,string,string,stringsongs: [one, two, three, four],// 数组的解构 => obj,obj,obj,objhistory: [first, second, third],} = wangfei;console.log(name); // 王菲console.log(age); // 18console.log(one); // 红豆console.log(first); // {name: '窦唯'}</script>
    </html>
    
  • 注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式

模板字符串

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

    • 字符串中可以出现换行符
    • 可以使用${xxx}形式输出变量
    <!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></head><body><ul></ul></body><script>const books = ["JavaScript", "Vue", "React", "Es6"];let str = "";for (let i = 0; i < books.length; i++) {str += `<li>${books[i]}</li>`;}// 获取 DOM 对象document.querySelector("ul").innerHTML = str;</script>
    </html>
    
  • 注意:当遇到字符串与变量拼接的情况使用模板字符串

简化对象写法

  • 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></head><body></body><script>let name = "张三";let age = 20;const sayHi = function () {console.log("hi");};// 原始写法let obj = {// key:value 的写法name: name,age: age,sayHi: sayHi,};console.log(obj); // {name: '张三', age: 20, sayHi: ƒ}// 简化写法let newObj = {// 当key与value一致时,就可以只写一个就可以了name,age,sayHi,};console.log(newObj); // {name: '张三', age: 20, sayHi: ƒ}const person = {sayHi: function () {console.log(11);},};// 对象中的方法后 :function 是可以省略的const newPerson = {sayHi() {console.log(11);},};</script>
    </html>
    
  • 注意:对象简写形式简化了代码,所以以后用简写就对了

箭头函数

  • 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></head><body></body><script>// => 代替 function()const oldFn = function () {console.log("oldFn"); // oldFn};oldFn();const fn = () => {console.log("fn"); // fn};fn();</script>
    </html>
    
  • 箭头函数的注意点:

    • 如果形参只有一个,则小括号可以省略

      <!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></head><body></body><script>// 箭头函数没有参数的情况const a = () => {console.log("没有参数的箭头函数");};a();// 箭头函数只有一个参数的情况(参数的括号可以省略)const b = (a) => {console.log("只有一个参数的箭头函数");};b();// 箭头函数的参数有多个时,不可以省略const c = (a, b) => {console.log(a, b); // 10 20};c(10, 20);</script>
      </html>
      

    • 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果

      <!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></head><body></body><script>// 代码函数只有一行,方法体的大括号可以省略const fo = () => console.log("代码函数只有一行,方法体的大括号可以省略");fo();// 代码行数只有一行,有返回值的情况,方法体的大括号和 return 可以省略的const sum = (a, b) => a + b;console.log(sum(10, 20));</script>
      </html>
      

    • 箭头函数this指向声明时所在作用域下this的值

      <!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></head><body></body><script>const obj = {name: "张三",age: 20,sayHi() {// thisconst _this = this;setTimeout(function () {// 计时器里面的 this 永远指向于 windowconsole.log(`你好,${_this.name}`);}, 2000);},};obj.sayHi();const obj2 = {name: "李四",age: 18,sayHi() {setTimeout(() => {// 箭头函数没有 this 指向,指向最近的 this// 这里受箭头函数的影响 this 指向 obj2console.log(`你好,${this.name}`);}, 2000);},};obj2.sayHi();</script>
      </html>
      

    • 箭头函数不能作为构造函数实例化

    • 不能使用arguments

      <!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></head><body></body><script>const fo = function () {console.log(arguments);};fo(1, 2, 3, 4);const foo = () => {// console.log(arguments); // 报错 arguments is not defined};foo(1, 2, 3);</script>
      </html>
      

  • 注意:箭头函数不会更改this指向,用来指定回调函数会非常合适

rest 参数

  • ES6引入rest参数,用于获取函数的实参,用来代替arguments

    <!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></head><body></body><script>const bar = function () {console.log(arguments instanceof Array); // false};bar(10, 20, 30, 40, 50, 60);// 箭头函数 rest 参数// 使用 ... 将剩余没有接收的参数放在数组中const foo = (...args) => {console.log(args instanceof Array); // true};foo(10, 20, 30, 40, 50, 60);const fn = (a, b, ...args) => {console.log(a, b, args);};fn(10, 20, 30, 40, 50, 60);</script>
    </html>
    

  • 注意:rest参数非常适合不定个数参数函数的场景

spread 扩展运算符

  • 扩展运算符(spread)也是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包

    <!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></head><body></body><script>// 展开数组let tfboys = ["德玛西亚之力", "德玛西亚之翼", "德玛西亚皇子"];function fn() {console.log(arguments);}fn(...tfboys);// 展开对象let skillOne = { q: "致命打击" };let skillTwo = { w: "勇气" };let skillThree = { e: "审判" };let skillFour = { r: "德玛西亚正义" };const gailun = { ...skillOne, ...skillTwo, ...skillThree, ...skillFour };console.log(gailun);// 数组的合并const a = [1, 2, 3, 4];const b = [5, 6, 7, 8];const c = a.concat(b);console.log(c); // [1, 2, 3, 4, 5, 6, 7, 8]const d = a.push(...b);console.log(d); // 8// 对象的合并const p1 = {name: "李四",age: 18,};const p2 = { ...p1, age: 30 }; // 在合并对象的时候 重复的属性会以最后一个出现的为准console.log(p2);</script>
    </html>
    

迭代器

  • 遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  • ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费

  • 原生具备iterator接口的数据(可用for of遍历)

    • Array
    • Arguments
    • Set
    • Map
    • String
    • NodeListDOM节点)
  • 工作原理

    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
    • 每调用next方法返回一个包含valuedone属性的对象
    • 注: 需要自定义遍历数据的时候,要想到迭代器
    <!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></head><body><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div></body><script>// const divs = document.querySelectorAll("div");// 获取到的 HTMLCollection 集合,没有办法 forEachconst divs = document.getElementsByTagName("div");// divs.forEach((item) => {//   console.log(item); // 报错 divs.forEach is not a function// });for (const item of divs) {console.log(item); // 这个是可以遍历的}const objArr = [{name: "Vuejs",price: 18,},{name: "React",price: 10,},{name: "Angular",price: 28,},];for (const item of objArr) {console.log(item);}</script>
    </html>
    

Promise

  • PromiseES6引入的异步编程的新解决方案

  • 语法上Promise是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。

    <!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></head><body></body><script>// 创建Promise的对象// 在创建Promise对象的时候,需要传入一个回调函数,// 这个回调函数会产生两个参数// 这两个参数是两个函数 resolve() 表示成功  reject() 失败const p = new Promise(function (resolve, reject) {setTimeout(() => {let a = 10;if (a == 10) {// 表示成功resolve(++a);} else {// 表示失败a = 20;reject(a);}}, 2000);});const p2 = new Promise((resolve, reject) => {// then表示成功// cath表示失败p.then((a) => {console.log(a); // 11if (a == 11) {resolve(++a);} else {reject(a);}}).catch((error) => {console.log(error);});});// p2.then(a=>{//   console.log(a);// })// p2.catch(error => {//   console.log(error);// })</script>
    </html>
    
  • Promise构造函数:Promise (excutor) {}

  • Promise.prototype.then方法

  • Promise.prototype.catch方法

  • Promise.prototype.all

Promise封装Ajax

  • Ajax

<!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></head><body></body><script>let xhr;// 创建XMLHttpRequest对象if (XmlHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XML");}// 监听状态xhr.onreadystatechange = () => {// post 201// get 200if ((xhr.readyState == 4) & (xhr.status == 200) || xhr.status == 201) {// 处理操作}};// 开启连接xhr.open("get", "xxxx", true);xhr.send();</script>
</html>
  • Promise封装Ajax

    function $http(params) {const { method, url, body, header } = params;return new Promise((resolve, reject) => {let xhr;if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();} else {xhr = new ActiveXObject("Microsoft.XMLHTTP");}xhr.onreadystatechange = () => {if (xhr.readyState == 4 && xhr.status == 200) {const { code, data } = JSON.parse(xhr.responseText);resolve(data);}};xhr.open(method, url);try {for (const key in header) {xhr.setRequestHeader(key, header[key]);}} catch (error) {console.log(error);}xhr.send(JSON.stringify(body));});}

Set

  • ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator接口,所以可以使用『扩展运算符』『for…of…』进行遍历,集合的属性和方法:

    <!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></head><body></body><script src="./http.js"></script><script>let s1 = new Set();console.log(s1);// 成员的值都是唯一的 所以可以做数组的去重let s2 = new Set([22, 2, 22, 34, 34, 22, 5]);// 得到一个去重的对象console.log(s2); // {22, 2, 34, 5}let newArr = [...s2];console.log(newArr); // [22, 2, 34, 5]</script>
    </html>
    

    • size返回集合的元素个数

    • add增加一个新元素,返回当前集合

    • delete删除元素,返回boolean

    • has检测集合中是否包含某个元素,返回boolean

    • clear清空集合,返回undefined

      <!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></head><body></body><script src="./http.js"></script><script>// size 返回集合的元素个数let s2 = new Set([10, 20, 20, 30, 40, 30]);console.log("size:" + s2.size); // size:4// add 增加一个新元素,返回当前集合console.log(s2.add(5)); // {10, 20, 30, 40, 5}// delete 删除元素,返回 boolean 值// .delete(某一个元素)console.log(s2.delete(20)); // trueconsole.log(s2); // {10, 30, 40, 5}// has 检测集合中是否包含某个元素,返回 boolean 值console.log(s2.has(10)); // truefor (const iterator of s2) {console.log(iterator);}// clear 清空集合,返回 undefinedconsole.log(s2.clear()); // undefined</script>
      </html>
      

Map

  • ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用『扩展运算符』『for…of…』进行遍历。Map的属性和方法:

    • size返回Map的元素个数
    • set增加一个新元素,返回当前Map
    • get返回键名对象的键值
    • has检测Map中是否包含某个元素,返回boolean
    • clear清空集合,返回undefined
    <!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></head><body></body><script src="./http.js"></script><script>const map = new Map([["name", "网星软件"],["slogon", "不断提高行业标准"],]);console.log(map); // {'name' => '网星软件', 'slogon' => '不断提高行业标准'}// size 返回 Map 的元素个数console.log(map.size); // 2// set 增加一个新元素,返回当前 Mapconsole.log(map.set("old", 13));// get 返回键名对象的键值console.log(map.get("old")); // 13// has 检测 Map 中是否包含某个元素,返回 boolean 值console.log(map.has("name")); // truefor (const item of map) {console.log(item);}// clear 清空集合,返回 undefinedconsole.log(map.clear()); // undefined</script>
    </html>
    

class

  • ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。知识点

    • class声明类
    • constructor定义构造函数初始化
    <!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></head><body></body><script src="./http.js"></script><script>// 创建类class Person {// 静态属性 可以直接被类名调用static type = "human";/*** 构造函数(构造方法) 不能写出箭头函数* 做初始化的*/constructor(name, age) {this.name = name;this.age = age;}/*** 普通函数* 关于对象的行为操作*/// sayHi() {//   console.log(`${this.name}:hi`);// }sayHi = () => {console.log(`${this.name}:hi`);};/*** 静态方法 被 static 修饰* 频繁使用的一些方法*/static talk() {console.log("讲话");}}const person = new Person("张三", 18);console.log(person);person.sayHi();// 静态方法可以直接被类名调用 无需创建对象Person.talk();console.log(Person.type); // human</script>
    </html>
    

    • extends继承父类
    • super调用父级构造方法
    • static定义静态方法和属性
    • 父类方法可以重写
    <!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></head><body></body><script src="./http.js"></script><script>// 定义 Person 类class Person {constructor(name, age) {this.name = name;this.age = age;}sayHi = () => {console.log(`${this.name}:hi`);};static talk() {console.log("讲话");}}// 定义 Student 类,并继承 Person,只能继承一个class Student extends Person {constructor(name, age, score) {// 交给父类super(name, age);// 自己的参数this.score = score;}// 子类可以重写父类中的方法sayHi = () => {console.log("hello");};static talk() {console.log("spack");}}const stu = new Student("张三", 18, 66);console.log(stu);stu.sayHi();Student.talk();</script>
    </html>
    

没有模块化产生的问题

  • 结构目录

  • 代码展示

    • bar.js

      var a = true;
      
    • foo.js

      var a = false;
      
    • index.html

      <!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></head><body></body><script src="./bar.js"></script><script src="./foo.js"></script><script>if (a) {// 没有内容打印 前面的var a把后面的var a给覆盖了,导致最后执行了foo.js里面的var a = false// 但是当你把 俩个文件引入的顺序换一下就会打印出来// 当你把这俩个文件看成俩个不同的人写的项目,这样就会造成项目之间的互相影响 也会使后期的代码不好维护console.log("a == true");}</script>
      </html>
      
  • 早期解决的办法:(闭包)

    • bar.js

      var bar = (function () {// 返回一个对象 这样我们就可以使用 对象.属性 的方式获取return {a: true,};
      })();
      
    • foo.js

      var foo = (function () {// 返回一个对象 这样我们就可以使用 对象.属性 的方式获取return {a: false,};
      })();
      
    • index.html

      <!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></head><body></body><script src="./bar.js"></script><script src="./foo.js"></script><script>if (bar.a) {console.log("a == true"); // a == true}</script>
      </html>
      
    • 这样虽然可以解决问题,但是当你一直在bar.jsfoo.jsreturn里面写代码,会发现非常臃肿。所以让我们看看下面ES6中的模块化。

模块化

  • 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
  • 模块化的优势有以下几点:
    • 防止命名冲突
    • 代码复用
    • 高维护性
    • 2.18.2.模块化规范产品
    • ES6之前的模块化规范有:
      • CommonJS=> NodeJS、Browserify
      • AMD => requireJS
      • CMD => seaJS

ES6 模块化语法

  • 模块功能主要由两个命令构成:exportimport

  • export命令用于规定模块的对外接口

    • export导出 将需要给别人使用的变量或者方法暴露出去
  • import命令用于输入其他模块提供的功能

    • import导入 将别人导出的变量和方法引入使用
  • 导出导入的方式(输出打印需要开启一个服务)

    • 目录结构

    • 单独导出

      • foo.js

        export const a = 10;
        
      • main,js

        // 程序的入口(主文件)// 导入方式一
        import * as foo from "./foo.js";
        console.log(foo.a); // 10
        
        // 程序的入口(主文件)// 导入方式二
        import { a } from "./foo.js";
        console.log(a); // 10
        
      • index,html

        <!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></head><body></body><script src="./main.js" type="module"></script>
        </html>
        
    • 统一导出

      • bar,js

        const name = "张三";const sum = function (a, b) {return a + b;
        };// 导出
        export { name, sum };
        
      • foo.js

        const a = 10;const sum = (a, b) => console.log(a + b); // 30export { a, sum };
        
      • main.js

        // 程序的入口(主文件)import * as bar from "./bar.js";
        import * as foo from "./foo.js";console.log(bar.name); // 张三
        console.log(bar.sum(10, 30)); // 40
        console.log(foo.a); // 10
        foo.sum(10, 20);
        
      • index,html

        <!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></head><body></body><script src="./main.js" type="module"></script>
        </html>
        
    • 默认导出(一个)

      • bar,js

        export default 10;
        
      • foo,js

        // 这里 a 前面不能加 const
        // 这里默认导出只能有一个 不可以写多个默认导出export default () => 10 + 20;
        
      • main,js

        // 程序的入口(主文件)import bar from "./bar.js";
        import foo from "./foo.js";console.log(bar); // 10
        console.log(foo()); // 30
        
      • index,html

        <!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></head><body></body><script src="./main.js" type="module"></script>
        </html>
        
    • 默认导出(多个)

      • foo.js

        const a = 10;
        const sum = () => 10 + 20;
        export default { a, sum };
        
      • main,js

        // 程序的入口(主文件)import foo from "./foo.js";console.log(foo.a); // 10
        console.log(foo.sum()); // 30
        
      • index,js

        <!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></head><body></body><script src="./main.js" type="module"></script>
        </html>
        

ES10 新增的模块化

  • 目录结构

  • 代码展示

    • data.js

      export const formatDate = () => new Date();
      
    • math.js

      export const radom = () => Math.random();
      
    • index.js

      // 统一导出
      // * 表示所有export * from "./data.js";
      export * from "./math.js";
      
    • main.js

      import { formatDate, radom } from "./index.js";console.log(formatDate());
      console.log(radom());
      
    • index.html

      <!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></head><body><script src="./main.js" type="module"></script></body>
      </html>
      

asyncawait

  • asyncawait两种语法结合可以让异步代码像同步代码一样
  • async函数的返回值为promise对象
  • promise对象的结果由async函数执行的返回值决定
  • await必须写在async函数中
  • await右侧的表达式一般为promise对象
  • await返回的是promise成功的值
  • awaitpromise失败了, 就会抛出异常, 需要通过try...catch捕获处理

Rest/Spread 属性

  • Rest参数与spread扩展运算符在ES6中已经引入,不过ES6中只针对于数组, 在ES9中为对象提供了像数组一样的rest参数和扩展运算符

    <!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></head><body></body><script>function connect({ host, port, ...user }) {console.log(host, port); // 127.0.0.1 8080console.log(user); // {username: 'admin', password: '123456', type: 'master'}}connect({username: "admin",password: "123456",host: "127.0.0.1",port: 8080,type: "master",});</script>
    </html>
    

ECMAScript(ES6)相关推荐

  1. ECMAScript 2015(ES6)规范中的promise

    ECMAScript 2015(ES6)规范中的promise – 转 概述 Promise 对象用于延迟(deferred) 计算和异步(asynchronous ) 计算..一个Promise对象 ...

  2. 理解 ES5, ES2015(ES6) 和 TypeScript

    理解 ES5, ES2015(ES6) 和 TypeScript 本文转载自:众成翻译 译者:kayson 链接:http://www.zcfy.cc/article/1332 原文:https:// ...

  3. 查看这些有用的ECMAScript 2015(ES6)提示和技巧

    by rajaraodv 通过rajaraodv 查看这些有用的ECMAScript 2015(ES6)提示和技巧 (Check out these useful ECMAScript 2015 (E ...

  4. Javascript语法精讲——ECMAScript(三)

    10.JavaScript-面向对象 10.1.JavaScript-面向对象基本概念 1.面向过程: 强调的是功能行为 关注的是解决问题需要哪些步骤 每一个具体步骤中我们都是参与方,并且需要面对具体 ...

  5. 前端学习-JavaScript基础(ES6)

    简介: ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并 ...

  6. Javascript语法精讲——ECMAScript(一)

    1.JavaScript基础-基本概念 1.1.什么是JavaScript? JavaScript简称JS,是前端开发的一门脚本语言(解释型语言). 解释型语言:程序执行之前,不需要编译就可以直接运行 ...

  7. JavaScript高级(ES6)

    JS高级学习笔记(中) 文章目录 JS高级学习笔记(中) 类(ES6) 类的构造函数 类的实例方法 类的静态方法(类方法) ES6类的继承 -- extends super关键字 JavaScript ...

  8. TypeScript(ES6)变量提升(Hoisting)

    ES6 新特性 ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const. let 声明的变量只在 let 所在的代码块内有效. const 声明一个只读的常 ...

  9. JavaScript数据结构与算法(1)(数组、栈、队列、链表)(ES6)

    注意:原教学视频:JavaScript(ES6)数据结构和算法 | JavaScript数据结构与算法 (都是CoderWhy老师的教学) 原作者(笔记)链接:JavaScript 数据结构与算法 | ...

最新文章

  1. Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)
  2. Java生成pgp密钥对_在Javascript中生成PGP密钥对,并使用加密的PGP私钥对文本进行签名...
  3. hibernate jpa_JPA / Hibernate实体状态转换的初学者指南
  4. 02 前端篇(选择器和属性)
  5. python调用metasploit自动攻击_Python脚本与Metasploit交互进行自动永恒之蓝攻击-Go语言中文社区...
  6. 家里没有wifi6设备,换wifi6路由器会有提升吗?
  7. 浏览器css透明属性opacity
  8. php模糊搜索 变量,自定义搜索seo变量{param}字符串
  9. 如何在 SQL Server 2005 故障转移群集中添加或删除节点(安装程序)
  10. mysql longbolb_MySql基本数据类型及约束
  11. 下列关于python2.x和3.x的区别说法正确_1.??下列关于Python2.x和Python3.x的说法,正确的是()...
  12. Servlet原理:
  13. 自动写诗APP项目、基于python+Android实现(技术:LSTM+Fasttext分类+word2vec+Flask+mysql)第一节
  14. ​​​​​​亲测有效|强制删除电脑上无法删除的文件和文件夹
  15. 学习笔记之 初试Linux遇到的问题
  16. 函数进阶 call apply bind 的区别
  17. OpenDaylight(ODL)学习笔记
  18. Vue项目打包部署到七牛CDN
  19. Educational Codeforces Round 92 (Rated for Div. 2)题解(A-C)
  20. HUD(蓝牙版)中蓝牙方案

热门文章

  1. ​PBlaze6上新!Memblaze发布首款基于长存颗粒的企业级SSD
  2. R语言散点图分类、配色、添加趋势线
  3. 开源商城系统-热猫商城店铺优惠和店铺智能排序、收益订单等功能更新
  4. 机器人蛮王_英雄联盟机器人被重做,变身上单霸主,机器人:蛮王、诺手你过来...
  5. 移动增值业务系统发展趋势分析
  6. H3C HCL MPLS 2层专线实验
  7. 第二十九节:Java基础知识-类,多态,Object,数组和字符串
  8. RocketMq客户端日志参数设置
  9. Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)
  10. hacking 麦步手表之(2)命令行编译工程