ECMAScript(ES6)
ECMAScript
ECMAScrit 简介
ECMA
(European Computer Manufacturers Association
)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为Ecma
国际。ECMAScript
是由Ecma
国际通过ECMA-262
标准化的脚本程序设计语言Ecma
国际制定了许多标准,而ECMA-262
只是其中的一个,所有标准列表查看- http://www.ecma-international.org/publications/standards/Standard.htm
ECMA-262 历史
ECMA
(European Computer Manufacturers Association
)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信第 1 版 1997年 制定了语言的基本语法 第 2 版 1998年 较小改动 第 3 版 1999年 引入正则、异常处理、格式化输出等。IE 开始支持 第 4 版 2007年 过于激进、未发布 第 5 版 2009年 严格模式、 JSON
、扩展对象、数组、原型、字符串、日期方法第 6 版 2015年 模块化、面向对象语法、 Promise
、箭头函数、let
、const
、数组解构赋值等等第 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
NodeList
(DOM
节点)
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的
next
方法,指针自动指向数据结构的第一个成员 - 接下来不断调用
next
方法,指针一直往后移动,直到指向最后一个成员 - 每调用
next
方法返回一个包含value
和done
属性的对象 - 注: 需要自定义遍历数据的时候,要想到迭代器
<!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
Promise
是ES6
引入的异步编程的新解决方案语法上
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
关键字,可以定义类。基本上,ES6
的class
可以看作只是一个语法糖,它的绝大部分功能,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.js
和foo.js
的return
里面写代码,会发现非常臃肿。所以让我们看看下面ES6
中的模块化。
模块化
- 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
- 模块化的优势有以下几点:
- 防止命名冲突
- 代码复用
- 高维护性
2.18.2.
模块化规范产品ES6
之前的模块化规范有:CommonJS=> NodeJS、Browserify
AMD => requireJS
CMD => seaJS
ES6 模块化语法
模块功能主要由两个命令构成:
export
和import
。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>
async
和 await
async
和await
两种语法结合可以让异步代码像同步代码一样async
函数的返回值为promise
对象promise
对象的结果由async
函数执行的返回值决定await
必须写在async
函数中await
右侧的表达式一般为promise
对象await
返回的是promise
成功的值await
的promise
失败了, 就会抛出异常, 需要通过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)相关推荐
- ECMAScript 2015(ES6)规范中的promise
ECMAScript 2015(ES6)规范中的promise – 转 概述 Promise 对象用于延迟(deferred) 计算和异步(asynchronous ) 计算..一个Promise对象 ...
- 理解 ES5, ES2015(ES6) 和 TypeScript
理解 ES5, ES2015(ES6) 和 TypeScript 本文转载自:众成翻译 译者:kayson 链接:http://www.zcfy.cc/article/1332 原文:https:// ...
- 查看这些有用的ECMAScript 2015(ES6)提示和技巧
by rajaraodv 通过rajaraodv 查看这些有用的ECMAScript 2015(ES6)提示和技巧 (Check out these useful ECMAScript 2015 (E ...
- Javascript语法精讲——ECMAScript(三)
10.JavaScript-面向对象 10.1.JavaScript-面向对象基本概念 1.面向过程: 强调的是功能行为 关注的是解决问题需要哪些步骤 每一个具体步骤中我们都是参与方,并且需要面对具体 ...
- 前端学习-JavaScript基础(ES6)
简介: ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并 ...
- Javascript语法精讲——ECMAScript(一)
1.JavaScript基础-基本概念 1.1.什么是JavaScript? JavaScript简称JS,是前端开发的一门脚本语言(解释型语言). 解释型语言:程序执行之前,不需要编译就可以直接运行 ...
- JavaScript高级(ES6)
JS高级学习笔记(中) 文章目录 JS高级学习笔记(中) 类(ES6) 类的构造函数 类的实例方法 类的静态方法(类方法) ES6类的继承 -- extends super关键字 JavaScript ...
- TypeScript(ES6)变量提升(Hoisting)
ES6 新特性 ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const. let 声明的变量只在 let 所在的代码块内有效. const 声明一个只读的常 ...
- JavaScript数据结构与算法(1)(数组、栈、队列、链表)(ES6)
注意:原教学视频:JavaScript(ES6)数据结构和算法 | JavaScript数据结构与算法 (都是CoderWhy老师的教学) 原作者(笔记)链接:JavaScript 数据结构与算法 | ...
最新文章
- Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)
- Java生成pgp密钥对_在Javascript中生成PGP密钥对,并使用加密的PGP私钥对文本进行签名...
- hibernate jpa_JPA / Hibernate实体状态转换的初学者指南
- 02 前端篇(选择器和属性)
- python调用metasploit自动攻击_Python脚本与Metasploit交互进行自动永恒之蓝攻击-Go语言中文社区...
- 家里没有wifi6设备,换wifi6路由器会有提升吗?
- 浏览器css透明属性opacity
- php模糊搜索 变量,自定义搜索seo变量{param}字符串
- 如何在 SQL Server 2005 故障转移群集中添加或删除节点(安装程序)
- mysql longbolb_MySql基本数据类型及约束
- 下列关于python2.x和3.x的区别说法正确_1.??下列关于Python2.x和Python3.x的说法,正确的是()...
- Servlet原理:
- 自动写诗APP项目、基于python+Android实现(技术:LSTM+Fasttext分类+word2vec+Flask+mysql)第一节
- ​​​​​​亲测有效|强制删除电脑上无法删除的文件和文件夹
- 学习笔记之 初试Linux遇到的问题
- 函数进阶 call apply bind 的区别
- OpenDaylight(ODL)学习笔记
- Vue项目打包部署到七牛CDN
- Educational Codeforces Round 92 (Rated for Div. 2)题解(A-C)
- HUD(蓝牙版)中蓝牙方案
热门文章
- ​PBlaze6上新!Memblaze发布首款基于长存颗粒的企业级SSD
- R语言散点图分类、配色、添加趋势线
- 开源商城系统-热猫商城店铺优惠和店铺智能排序、收益订单等功能更新
- 机器人蛮王_英雄联盟机器人被重做,变身上单霸主,机器人:蛮王、诺手你过来...
- 移动增值业务系统发展趋势分析
- H3C HCL MPLS 2层专线实验
- 第二十九节:Java基础知识-类,多态,Object,数组和字符串
- RocketMq客户端日志参数设置
- Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)
- hacking 麦步手表之(2)命令行编译工程