ES6 超详细版 0. 前言 1. 关于文章内容 本教程根据作者观看B站Up主 @IT峰播 后由自己总结得来, 视频地址: Vue3.x IT峰播
自定义为扫盲文章,其内容并不全(当然除了官方文档或者全部照着官方文档写出来的其他都不能叫全)
涵盖了较为常用的知识点,您可以在全面系统学习es6之前进行阅读,或不是很熟悉es6的人进行学习补充
由于内容绝大多数由作者手打, 无法避免的会有些错误或瑕疵,或因理解方向不同等造成失误,还请斧正
2. 关于文章主题 为方便阅读, 本文使用juejin主题, 如有不适, 敬请谅解
1. let and const 1. let let用于声明变量
有局部作用域
1 2 3 4 5 { let a = 10 ; } console .log (a);复制代码
let声明的变量不会提升
1 2 3 console .log (a); let a = 10 ;复制代码
2. const const用于声明常量
1 2 3 const name = '张三' ;复制代码
const声明的常量也不会提升
1 2 3 console .log (name); const name = '张三' ;复制代码
const声明对象时,该对象不可以更换,但是对象里的内容可以更改
1 2 3 4 5 6 7 8 9 const person = { name :'张三' , age :18 }; console .log (person);person.age = 19 ; console .log (person); 复制代码
2. 箭头函数 1. 使用方法 理解为一般函数去掉function关键字再在参数和函数语句块中间加上=>
1 2 3 4 5 6 7 8 9 function myfunction (x ){ return x*x } console .log (myfunction (3 )) const myFunc =(x )=>{return x * x} console .log (myFunc (3 )) 复制代码
如果只有一个参数,可以去掉括号(注意没有参数时也要加上()占位)
1 2 3 const myFunc = x =>{return x * x}console .log (myFunc (3 )) 复制代码
如果只有一条返回语句,可以再去掉return和{ }
1 2 3 const myFunc = x => x * xconsole .log (myFunc (3 )) 复制代码
箭头函数在返回对象时必须在对象外层多加一个()
1 2 3 4 5 6 7 8 9 const fun = id=>{({id :id, name :'张三' })}console .log (fun (10 ).name )复制代码
this 与普通函数的this不同, 普通函数谁调用这个函数,this就是指向谁 箭头函数没有自己的this,它的this继承于父级, 也就是箭头函数的this指向箭头函数所处对象
3. 数组新增的高级方法 三个方法:
filter() map() reduce() 他们都会接收一个函数,然后数组有多长,就执行多少次函数 相当于循环这个数组并每次对数组元素使用这个函数
1. filter() 过滤 1 2 3 4 5 6 7 8 9 let myArray=[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]; let array1 = myArray.filter (function (n ){ return n>5 ; }) console .log (array1) 复制代码
2. map() 1 2 3 4 5 6 7 8 9 let array2 = array1.map (function (n ){ return 2 *n; }) console .log (array2) 复制代码
3. reduce() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let sum = 0 ;sum = array2.reduce (function (s,n ){ return s+n; },0 ) console .log (sum)复制代码
4. Map 与 Set 数据结构 5. 字符串新增方法与模板字符串 1. 字符串新增方法 1. startswith(string) String.startswith(string) 判断String是否以string开头 返回true或false
1 2 3 4 5 6 7 let url='www.baidu.com' ;if (url.startsWith ('https' )){ console .log (url) }else { console .log ('不是以https开头的url' ) } 复制代码
2. endswith(string) String.endswith(string) 判断String是否以string结尾
1 2 3 4 5 6 if (url.endsWith ('.com' )){ console .log (url) }else { console .log ('不是以.com结尾的url' ) } 复制代码
2. 模板字符串 即字符串的增强版
可以在其中随意书写, 所写即所得,不像普通的字符串一样换行需要特殊符号,换行书写需要多加引号 1 2 3 4 5 6 7 8 9 let str = ` first second third something anything ` 复制代码
可以在字符串中引入其他变量,而不必像普通字符串一样写为 string + 变量 + string 1 2 3 4 5 6 7 8 let name = 'zhangsan' ;let age = 10 ;let normalStr = name+ ' is ' + age + ' years old' ;let templateStr = `${name} is ${age} years old` 复制代码
6. 解构赋值 对于普通数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let arr = [1 ,2 ,3 ];{ let a = arr[0 ]; let b = arr[1 ]; let c = arr[2 ]; } { let [a, b, c] = [1 , 2 ,3 ]; } { let [a, b, c] = arr; } 复制代码
对于对象 1 2 3 4 5 6 7 8 9 10 11 let person = { name :'zhangsan' , age :10 , gender :'male' } { let {name, age, gender} = person; console .log (name, age, gender) } 复制代码
如果是对象的话,左边的变量名称必须和右边的名字相同,否则失败,仍为undefined 1 2 3 4 5 6 { let {anotherName, age, gender} = {name :'zhangsan' , age :10 , gender :'male' }; console .log (anotherName, age, gender) } 复制代码
普通值左边的值可以少于右边的值,会按顺序赋值 1 2 3 4 5 6 let arr = [1 ,2 ,3 ];{ let [a, b] = arr; console .log (a,b); } 复制代码
对象左值也可以少于右边的,且顺序可以改变,因为对象按键名来赋值 1 2 3 4 5 6 7 8 9 10 let person = { name :'zhangsan' , age :10 , gender :'boy' } { let {gender, age} = person; console .log (gender, age) } 复制代码
复合赋值 1 2 3 4 5 6 7 let arr = [{name :'zhangsan' , age :10 }, [1 ,2 ,3 ], 'hello' , 9 ];{ let [a,b,c,d] = arr; console .log (a); console .log (b,c,d); } 复制代码
分解赋值 1 2 3 4 5 6 7 8 9 let arr = [{name :'zhangsan' , age :10 }, [1 ,2 ,3 ], 'hello' , 9 ];{ let [{name,age},[a,b,c],d,e] = arr; console .log (name,age); console .log (a,b,c); console .log (d,e); } 复制代码
声明与赋值不可分开 7. 三点拓展运算符 1. 拓展数组 将array1数组放入myArray最前端, 将array2数组放入myArray最后端 1 2 3 4 5 let array1 = [1 ,2 ,3 ];let array2 = [7 ,8 ,9 ];let myArray = [...array1, 4 , 5 , 6 , ...array2] ;console .log (myArray) 复制代码
数组各元素作为参数时,可以使用三点拓展运算符对数组进行解构传入 1 2 3 4 5 6 7 8 9 function myFunction (a, b, c ) { console .log (a,b,c); return a+b+c; } let arr = [1 ,2 ,3 ];console .log (myFunction (...arr)); 复制代码
利用三点拓展运算符将参数列表转化为一个数组 通过2中我们知道,传入实参时使用三点运算符,会把数组各个元素转化为单独的变量 那如果形参使用三点运算符,实参传入单独的变量,那么在函数中是不是就成了一个数组呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function myFunction (...arr ) { for (let i = 0 ; i <arr.length ; i++) { console .log (arr[i]); } console .log (arr); } myFunction (3 ,12 ,45 ,123 );复制代码
参数中部分使用三点拓展运算符 1 2 3 4 5 6 function myFunction (a,b, ...arr ){ console .log (arr); } myFunction (1 ,2 ,3 ,4 ,5 ,6 ,7 ); 复制代码
8. 对象的新语法 1. 新增类的概念 使用class创建类,使用constructor创建构造函数 1 2 3 4 5 6 7 8 9 10 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } } 复制代码
类中方法不需要关键词function 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } 复制代码
使用new来创建类的实例,并传入参数(如果有的话) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } let person1 = new Person ('zhangsan' , 18 , 'male' ) 复制代码
使用对象里的方法等使用 . 运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } let person1 = new Person ('zhangsan' , 18 , 'male' );person1.say (); 复制代码
使用extends继承父类, 继承后所有父类属性和方法都会被继承过来 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } class Students extends Person {} student1 = new Students ('lisi' , 19 , 'male' , '8003119501' ) console .log (student1.name ) student1.say (); student1.age = 20 ; student1.say (); 复制代码
子类中super()可以使用父类的构造方法, 默认使用父类的构造方法, 如果自己加入constructor(){}则会覆盖父类的构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } class Students extends Person { construtor ( ){ } } student1 = new Students ('lisi' , 19 , 'male' , '8003119501' ) 复制代码
使用super()简化子类的构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } class Students extends Person { construtor (name, age, gender, id ){ super (name, age, gender); this .id = id; } } student1 = new Students ('lisi' , 19 , 'male' , '8003119501' ) console .log (student1);student1.say (); 复制代码
重写父类方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Person { constructor (name, age, gender ){ this .name = name; this .age = age; this .gender = gender; } say ( ) { console .log (this .name +' ' +this .age +' ' +this .gender ); } } class Students extends Person { construtor (name, age, gender, id ){ super (name, age, gender); this .id = id; } say ( ){ console .log (this .name , this .age , this .gender , this .id ); } } student1 = new Students ('lisi' , 19 , 'male' , '8003119' ) student1.say (); 复制代码
2. json 简写变量,值使用变量的时候,如果键名与变量名相同,那么可以写作一个 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 name = 'lisi' ; age = 14 ; sex = 'male' ; let obj = { name, age, gender :sex } 复制代码
简写方法, 方法也可以简写,不必function_name:function(){} 1 2 3 4 5 6 7 8 9 10 11 12 name = 'zhangsan' ; age = 15 ; let obj = { name, age, say ( ){ console .log (this .name , this .age ) } } obj.say (); 复制代码
使用JSON.stringify()进行串行化 1 2 3 4 5 6 7 8 9 10 name = 'zhangsan' ; age = 15 ; let obj = { name, age } let str = JSON .stringify (obj);console .log (str.name ) console .log (str) 复制代码
使用JSON.parse()进行反串行化 1 2 3 let obj = JSON .parse ('{"name":"lisi","age":19}' )console .log (obj.name , obj.age ) 复制代码
9. 模块化编程 1. module的引入 在编写html文件时,我们通常会引入许多js文件,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!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 > <script src ="./1.js" > </script > <script src ="./2.js" > </script > <script src ="./3.js" > </script > </head > <body > </body > </html > 复制代码
当这些js文件中有重复命名时,便会报错 如1.js和2.js都定义一个变量name
1 2 3 4 5 6 let name = 'zhangsan' ;复制代码 let name = 'lisi' ;复制代码
那么我们在最开始那样引入三个js文件会导致变量名冲突,报错如下: Uncaught SyntaxError: Identifier ‘name’ has already been declared 因为这样引入js会导致浏览器不知道解析那个name变量
我们可以给script标签的type属性赋值为module
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!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 > <script src ="./1.js" type ='module' > </script > <script src ="./2.js" type ='module' > </script > <script src ="./3.js" type ='module' > </script > </head > <body > </body > </html > 复制代码
这样相当于让每个js文件属于一个模块,这样便不会报错 相同的变量name属于不同的模块,就有了区分的标准
2. 如何访问不同js文件下相同的变量 每个module都是封闭的,但我们可以将它的属性暴露出去
1 2 3 4 5 6 7 let name = 'zhangsan' ;function add (a, b ){return a+b}export {name, add}; 复制代码
这样在1.js中就将name暴露出去了 但为了防止一暴露出去其他js文件就都可以访问,我们还有个引入功能import
1 2 3 4 5 6 7 8 9 10 import {name, add} from './1.js' ; console .log (name); console .log (add (3 , 9 )); 复制代码
3. 如何解决引入后的命名冲突 当我们从其他文件引入变量后,也可能出现命名重复
1 2 3 4 import {name} from './1.js' ;import {name} from './2.js' ;复制代码
这时候我们可以采用取别名的方法
1 2 3 4 5 import {name as name1} from './1.js' ;import {name as name2} from './2.js' ;复制代码
同样的你也可以在1.js或者2.js暴露属性时取别名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let name = 'zhangsan' ;export {name as name1};复制代码 let name = 'lisi' ;export {name as name2};复制代码 import {name1} from './1.js' ;import {name2} from './2.js' ;console .log (name1, name2); 复制代码
4. 定义属性时暴露 我们可以在定义属性时就将他暴露出去
1 2 3 export let name = 'zhangsan' ;复制代码
这样暴露出去的属性在本文件中仍能使用
1 2 3 4 export let name = 'zhangsan' ;console .log (name); 复制代码
5. 缺少名字的暴露属性 函数或类等可以不用取名字就直接暴露
1 2 3 4 5 export default function (a ){ console .log (a) } 复制代码
接收时名字不需要{}
1 2 3 4 import printa from './1.js' 复制代码
每个js文件只能定义这样的一个export default,
1 2 3 4 5 6 7 8 export default function (a ){ console .log (a) } export default function (a ){ return b; } 复制代码
如果出现两个及以上, 那么像
1 2 3 4 5 6 7 import printa from './1.js' import printb from './1.js' 复制代码
这样的引入方法便不知道引入哪个未命名的暴露了
6. 接收暴露的所有属性 你可以将某个js文件暴露的属性全部导入,并将其放入一个对象中以便访问
1 2 export * as name from 'url' ;