初始ES6 ECMAScript是一种由Ecma国际 (前身为欧洲计算机制造商协会 ,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言 。这种语言在万维网 上应用广泛,它往往被称为JavaScript 或JScript ,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。
从es6开始,每年发布一个版本,版本号比年份最后以为大1
ES5——2009年发布 ES6 ——2015年发布 ES7 ——2016年发布
完整的JavaScript实现包含三个部分:ECMAScript ,文档对象模型 ,浏览器对象模型。ECMAScript 是JavaScript的标准
(1)ECMAScript:描述了该语言的语法和基本对象。
(2)DOM:文档对象模型(DOM),描述处理网页内容的方法和接口。
(3)BOM:浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口。
变量声明 let 声明变量 1 2 3 4 5 6 7 let a;let b,c,d;let e = 100 ;let f = 123 , g = 'wsjd' , h;
特性 1.变量不能重复声明
1 2 let star = ‘1 ’;let star = ‘2 ’;
2.有块级作用域{},var没有块级作用域,只有全局,函数,eval
1 2 3 4 if {let a = '1' ;} console .log (a);
3.不存在变量提升
1 2 console.log(b); //报错,获取不到b的值 let b = '1';
1 2 3 4 5 6 7 8 console .log (b); var b = '1' ;var b;console .log (b); var b = '1' ;
4.不影响作用域链
1 2 3 4 5 6 7 { let s = '1' ; function fn ( ){ console .log (s); } fn (); }
const 声明常量 const S = ‘1’;
特性 1.一定要赋初始值
const A;
2.一般常量使用大写
3.常量的值不能修改
4.块级作用域{}
5.对于数组和对象的元素修改,不算做对常量的修改,不会报错
1 2 const M = ['1' , '2' , '3' ];M.push ('4' );
变量的解构赋值 数组的结构 1 2 3 4 5 6 const f = ['1' ,'2' ,'3' ,'4' ];let [a, b, c, d] = f;console .log (a); console .log (b); console .log (c); console .log (d);
对象的解构 1 2 3 4 5 6 7 8 9 10 11 12 13 const z = { name : 'zhang' , age : '18' , study : function ( ){ console .log ("111" ); } }; let {name, age, study} = z;console .log (name); console .log (age); console .log (study); study ();
模板字符串
ES6引入新的声明字符串方式:``(反引号),以前的声明方式有 ‘’,””,
声明
特性 1.内容中可以直接出现换行符(), ‘’,””不能出现
1 2 3 4 5 6 let str = `<ul> <li>a</li> <li>a</li> <li>a</li> <li>a</li> </ul>`
变量拼接 ${}
1 2 3 let a = "hello" ;let b = `${a} world` ;console .log (b);
简化写法 对象简化写法 1 2 3 4 5 6 7 8 let name = 'a' ;let ab = function ( ){ console .log ('111' ); } const s = { name, ab }
函数简化写法 1 2 3 4 5 6 7 8 fn : function ( ) {} fn ( ){}
函数形参赋初值
ES6允许给函数参数赋初始值
1、形参初始值,具有默认值的参数,一般位置要靠后
1 2 3 4 5 function add (a,b,c=10 ) { return a+b+c; } let result = add (1 ,2 ); let result1 = add (1 ,2 ,3 );
2、与解构赋值结合
1 2 3 4 5 6 7 8 9 function connect ({host="127.0.0.1" ,username,password,port} ){ console .log (host,username,password,port) } connect ({ host : 'baidu.com' , username : 'root' , password : 'root' , port : 3306 })
箭头函数
ES6允许使用箭头(=>)定义函数
声明 1 2 3 4 5 6 7 8 let fn = function (a,b){} let fn =(a,b)=> {}
特性 1.this是静态的,this始终指向函数声明时所在作用域下的this的值
2.不能作为构造函数实例化对象
3.不能使用arguments变量(普通函数用来保存实参)
4.箭头函数简写
(1)省略小括号,当形参有且只有一个
(2)省略花括号,当代码体只有一条语句的时候,此时return必须省略,语句的执行结果就是返回值
箭头函数适合与this无关的回调,定时器,数组的方法回调
不适合与this有关的回调,事件回调,对象的方法
rest参数
ES6引入rest参数,用于获取函数的实参,用来代替arguments
rest参数写法: …+参数名
arguments是对象,rest参数是数组
1 2 3 4 5 6 7 function fn (a,b,...args ){ console .log (a); console .log (b); console .log (args); } fn (1 ,2 ,3 ,4 ,5 ,6 )
扩展运算符
...
扩展运算符能将数组转化为逗号分割的参数序列
1 2 3 4 5 6 7 8 const tf = ['yy' ,'wy' ,'wjk' ];function chunwan ( ){ console .log (arguments ); } chunwan (...tf);
应用 1、数组的合并
1 2 3 4 const a = ['1' ,'2' ];const b = ['3' ,'4' ];const c = a.concat (b); const d = [...a,...b];
2、数组的克隆
1 2 const e = ['1' ,'2' ,'3' ];const f = [...e];
如果e数组内部包含对象等引用类型,则依然是浅拷贝
3、将伪数组转为真正的数组
1 2 3 const divs = document .querySelectorAll ('div' ); const divArr = [...divs];console .log (divArr);
Symbol类型
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,是一种类似于字符串的数据类型
特点 1、Symbol的值是唯一的,用来解决命名冲突的问题
2、Symbol值不能与其他数据进行运算
3、Symbol定义的对象属性不能使用for…in循环遍历,但可以使用Reflect。ownKeys来获取对象的所有键名
1 2 3 4 5 6 7 8 //创建Symbol let s = Symbol(); //可以加一个参数,类似于注释 let s1 = Symbol('苹果'); //函数 let s2 = Symbol('苹果'); //s1 !== s2 //Symbol.for创建唯一Symbol值 let s4 = Symbol.for('土豆'); //对象 let s5 = Symbol.for('土豆'); //s4 === s5
七种基本类型:number string boolean undefined null object Symbol
作用 用来定义对象的私有属性
1 2 3 4 5 6 7 8 9 let s1 = Symbol ('s1' );let obj = { [s1]: '苹果' }; console .log (obj[s1]); let s = Object .getOwnPropertySymbols (obj);let m = Reflect .ownKeys (obj);
Symbol内置属性
Symbol内置的属性是固定写法,整体作为对象的属性来设置,来改变
对象在特定场景的表现
迭代器 迭代器(Iterator)是一种接口,为各种不同数据提供统一的访问机制,任何数据结构只要部署Iterator接口(对象里的一个属性,属性名为Symbol.iterator)
,就可以完成遍历操作
1、es6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
2、原生具备iterator接口的数据(可用for of遍历)
array arguments set map string typedArray nodeList
1 2 3 4 5 6 7 8 //使用for...of遍历数组 const m = ['苹果','栗子','葡萄'] for(let v of m){ console.log(v) // 苹果 //栗子 //葡萄 } for(let v in m){ console.log(v) // 0 //1 //2 }
for...in遍历v是键名,for...of是遍历键值
1 2 3 4 5 6 7 8 9 10 Vue: V-for循环遍历数组时,可以选择in或of结果相同,推荐使用of,语法格式为`(item,index)` - item:迭代时不同的数组元素的值 - index:当前元素的索引 V-for循环遍历对象时推荐使用in,语法格式为`(item,name,index)` - item:迭代时对象的键名键值 - name:迭代时对象的键名 - index:当前元素的索引 在遍历对象时,会按 `Object.keys()` 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。 v-for也可以在实现了可迭代协议的值上使用,包括原生的Map和Set。
3、工作原理
创建一个指针对象,指向当前数据结构的起始位置
第一次调用对象的next方法,指针自动指向数据结构的第一个成员
不断调用next方法,指针一直向后移动直到指向最后一个成员
每调用next方法返回一个包含value和done属性的对象
1 2 3 4 5 6 7 8 const m = ['苹果' ,'栗子' ,'葡萄' ];let iterator = m[Symbol .iterator ]();console .log (iterator.next ()); console .log (iterator.next ()); console .log (iterator.next ()); console .log (iterator.next ());
迭代器应用 1、自定义遍历数据
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 const banji = { name : "zz" , stus : [ 'xiaom' , 'xiaoy' , 'xiaoz' ], [Symbol .iterator ]() { let index = 0 ; let self = this ; return { next : function ( ) { if (index < self.stus .length ){ const result = {value : self.stus [i], done : false }; index++; return result; }else { return {value : underfined,done :true }; } } } } } for (let v of banji) { console .log (v) } banji.stus .forEach ();
生成器函数 生成器函数声明调用 生成器函数是ES6提供的一种异步编程解决方案
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 function * gen ( ){ console .log ('hello world' ) } let iterator = gen ();console .log (iterator) iterator.next (); function * gen ( ){ console .log (111 ); yield 'aaa' ; console .log (222 ); yield 'bbb' ; console .log (333 ); yield 'ccc' ; console .log (444 ) } let iterator = gen ();console .log (iterator) iterator.next (); iterator.next (); iterator.next (); iterator.next (); console .log (iterator.next ()) console .log (iterator.next ()) console .log (iterator.next ()) console .log (iterator.next ())
生成器函数参数传递 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function * gen (arg ){ console .log (arg); let one = yield 'aaa' ; console .log (one) let two = yield 'bbb' ; console .log (two) yield 'ccc' ; } let iterator = gen ('111' );console .log (iterator.next ()) console .log (iterator.next ('222' )); console .log (iterator.next ('333' ))
生成器函数实例 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 function getUsers ( ){ setTimeout (()=> { let data = '用户数据' ; iterator.next (data); }, 1000 ); } function getOrders ( ){ setTimeout (()=> { let data = '订单数据' ; iterator.next (data); }, 1000 ); } function getGoods ( ){ setTimeout (()=> { let data = '商品数据' ; iterator.next (data); }, 1000 ); } function * gen ( ){ let users = yield getUsers (); console .log (users); let orders = yield getOrders (); console .log (orders); let goods = yield getGoods (); console .log (goods); } let iterator = gen ();iterator.next ()
Promise Promise是es6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
调用then方法,then方法的返回结果也是promise对象,对象状态由回调函数的执行结果决定,所以通过then方法可以执行链式调用
1、如果回调函数中返回的结果是非promise类型的属性,则对象状态是成功,返回值为对象成功的值
2、如果回调函数中返回的结果是promise类型的属性,则内部返回的promise对象状态决定返回对象状态
3、如果抛出错误,则返回对象状态为错误状态,返回值为抛出的错误值
1 2 3 4 5 6 7 8 9 10 11 12 13 const result = p.then (value => { console .log (value); }) throw new Error ('出错' ) })
Promise链式调用 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 <script> var f1=function ( ){ return new Promise (function (resolve, reject ) { setTimeout (()=> { let data = 'a' ; resolve (data) },1000 ) }) }; var f2=function (data ){ return new Promise (function (resolve, reject ) { setTimeout (()=> { let datas = data +'b' resolve (datas) },1000 ) }) }; var f3 = function (data ){ return new Promise (function (resolve, reject ) { setTimeout (function ( ) { let datas = data +'c' resolve (datas) },1000 ) }) }; f1 ().then (function (data ) { return f2 (data); }).then (function (data1 ) { return f3 (data1); }).then (function (data2 ) { console .log (data2) }).catch (res => { console .log (res) }) </script>
集合介绍和API ES6提供了新的数据结构Set(集合),它类似于数组,但成员的值是唯一的,集合实现了iterator接口,可以使用扩展运算符和for…of遍历。
集合的属性和方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 let s = new Set ();let s2 = new Set (['1' ,'2' ,'3' ]);console .log (typeOf (s)) console .log (s2) console .log (s2.size );s2.add ('4' ); s2.delete ('1' ); console .log (s2.has ('3' ));s2.clear (); for (let v of s2) { console .log (v) }
集合的使用 1 2 3 4 5 6 7 8 9 10 11 12 let arr = [1 ,2 ,3 ,4 ,5 ,4 ,3 ,2 ,1 ];let result = [...new Set (arr)];console .log (result); let arr2 = [4 ,5 ,6 ,5 ,6 ];let result = [...new Set (arr)].filter (item => new Set (arr2).has (item))let union = [...new Set ([...arr, ...arr2])];let diff = [...new Set (arr)].filter (item => !(new Set (arr2).has (item))console .log (diff)
Map ES6提供了新的数据结构Map,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用扩展运算符和for… of 进行遍历。
属性和方法 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 let m = new Map ();m.set ('name' ,'abb' ); m.set ('change' , function ( ){ console .log ('111' ) }) let key = { school : 'hbg' }; m.set (key, ['a' ,'b' ]) console .log (m); "name" => "abb" , "change" => function ( ){console .log ('111' )}, {school : 'hbg' } : ['a' ,'b' ] } m.delete ('name' ); console .log (m.get ('change' ));console .log (m.get (key));m.clear (); for (let v of m){ console .log (v) } m.size ();
class类 ES6提供了更接近传统语言的写法,引入了class(类)的概念,作为对象的模板。通过class关键字,可以定义类。基本上ES6的class可以看作只是一个语法糖,它的绝大部分功能ES5都可以做到,新的class’写法只是让对象原型的写法更加清晰,更像面向对象编程的语法。
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 40 41 42 43 function Phone (brand,price ){ this .brand = brand; this .price = price; } Phone .prototype .fn = function ( ){ console .log ('aaa' ) } let Huawei = new Phone ('华为' ,5999 );Huawei .fn ();console .log (Huawei ) { brand : '华为' , price: '5999' , __proto__ :{ call :fn :function ( ){console .log ('aaa' )} } } class Shouji { constructor (brand, price ){ this .brand = brand; this .price = price; } fn ( ) { console .log ('aaa' ) } } let onePlus = new Shouji ('1+' , 1999 )console ,log (onePlus ) { brand : '1+' , price: '1999' , __proto__ :{ call :fn :function ( ){console .log ('aaa' )} } }
class静态成员 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function Phone ( ){} Phone .name = 'shouji' ;Phone .prototype .size = '5' ;let nokia = new Phone ();console .log (nokia.name ); console .log (nokia.size ) class Phone { static name = 'shouji' ; static change ( ){ console .log ('wk' ); } } let nokia = new Phone ();console .log (nokia.name ); console .log (Phone .name )
类继承 1、ES5对象继承
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 40 41 42 43 44 45 function Phone (brand, price ) { this .brand = brand; this .price = price } Phone .prototype .ff = function ( ){ console .log ('aaa' ) } function SmartPhone (brand, price, color, size ){ Phone .call (this ,brand,price); this .color = color; this .size = size } SmartPhone .prototype = new Phone ;SmartPhone .prototype .constuctor = SmartPhone ;SmartPhone .prototype .photo = function ( ){ console .log ('111' ) } const chuzi = new SmartPhone ('cz' ,2499 ,'黑色' ,'5' );console .log (chuzi);{ brand : "cz" , color : "黑色" , price : 2499 , size : "5" , __proto__ : { brand : underfined, consturctor : function SmartPhone (brand, price, color, size ){}, photo : function ( ){ console .log ('111' ) }, price : underfined, __proto__ : { ff :function ( ){ console .log ('aaa' ) }, consturctor : function Phone (brand, price ){}, __proto__ : Object }, } }
2、class的类继承
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 40 41 42 43 44 class Phone { constructor (brand,price ){ this .brand = brand; this .price = price }, ff ( ){ console .log ('aaa' ) } } class SmartPhone extends Phone { constructor (brand,price,color,size ){ super (brand, price); this .color = color; this .size = size } photo ( ){ console .log ('111' ) } } const xiaomi = new SmartPhone ('xiaomi' ,1499 ,'黑色' ,'4' );console .log (xiaomi){ brand : "xiaomi" , color : "黑色" , price : 1499 , size : "4" , __proto__ : { consturctor : class SmartPhone photo : function ( ){ console .log ('111' ) }, __proto__ : { ff :function ( ){ console .log ('aaa' ) }, consturctor : class Phone __proto__ : Object }, } }
class中getter和setter设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Phone { get price (){ console .log ("价格属性被读取了" ); return '111' } set price (newVal ){ console .log ("价格属性被读取了" ); return '111' } } let s = new Phone ();console .log (s.price ); s.price = 'free' ;
当执行获取实例对象price属性时,就会执行get的函数,并将return的值返回,执行设置price时,就会执行set的函数。
ES6的数值扩展 1、Number.EPSTION是js表示的最小精度
1 2 3 4 5 6 7 8 9 function equal (a,b ){ if (Math .abs (a-b) < Number .EPSTION ){ return ture; }else { return false } } console .log (0.1 +0.2 === 0.3 ) console .log (equal (0.1 +0.2 ,0.3 ))
2、二进制和八进制
let b = 0b1010;
let o = 0o777;
let d = 100;
let x = 0xff;
3、Number.isFinite() 检测一个数值是否为有限数
4、Number.isNaN() 检测一个数值是否是NaN
5、Number.parseInt() Number.parseFloat()字符串转整数
6、Number.isInteger())判断一个数为整数
7、Math.trunc将数字的小数部分抹掉
8、Math.sign判断一个数到底为正数,负数还是零,返回1,0,-1
ES6对象方法扩展 1、Object.is 判断两个值是否完全相等
1 2 3 console .log (Object .is (120 ,120 )) console .log (Object .is (NaN ,NaN )) console .log (NaN === NaN )
2、Object.assign 对象的合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const config1 = { host : 'localhost' , port : 3306 , name : 'aa' } const config2 = { host : 'http://baidu.com' , port : 3316 , pass : 'bb' } console .log (Object .assign (config1, config2)) { name : 'aa' , host : 'http://baidu.com' , port : 3316 , pass : 'bb' }
3、Object.setPrototypeOf 设置原型对象 Object.getPrototypeOf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const school = { name : 'aa' } const cities = { xiaoqu : ['a' ,'b' ,'c' ] } Object .setPrototypeOf (school,cities); console .log (school);{ name : "aa" , __proto__ :{ xiaoqu : ['a' ,'b' ,'c' ], __proto__ : Object } } console .log (Object .getPrototypeOf (school))
模块化 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
模块化的优点 1、防止命名冲突
2、代码复用
3、高维护性
模块化规范产品 ES6之前的模块化规范(没有自己的模块化,引用社区规范)有:
1、 CommonJS =》 NodeJS Browserify
2、 AMD =》 requireJS
3、CMD =》 seaJS
ES6模块化语法 模块功能主要由两个命令组成: import 、export
export 命令用于规定模块的对外接口
import命令用于输入其他模块提供的功能
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 > </head > <body > <script type ="module" > import * as m1 from "./m1.js" console .log (m1.school ); m1.teach () </script > </body > </html >
1 2 3 4 5 export let school = 'a' ;export function teach ( ) { console .log ('111' ) }
ES6模块暴露语法 1、分别暴露—–上方m1.js
2、统一暴露——m2.js
1 2 3 4 5 6 7 8 9 10 let school = 'a' ;function teach ( ) { console .log ('111' ) } export {s, teach}import * as m2 from "./m2.js" console .log (m2.school ); m2.teach ()
3、默认暴露——–m3.js
1 2 3 4 5 6 7 8 9 10 export default { school : 'a' , teach : function ( ) { console .log ('111' ) } } import * as m3 from "./m3.js" m3.default .teach ();
ES6模块引入语法 1、通用导入方式
1 import * as m1 from "./m1.js" //相当于把所有赋值给m1
2、解构赋值方式
1 2 3 import {school, teach} from "./m1.js" import {school as newSchool, teach as teachfn} from "./m2.js" //若是命名冲突,使用as赋予新名字解决 import {default as m3} from "./m1.js"
3、简便形式(只能针对export default使用)
1 import m3 from "./m1.js"
babel对于ES6模块化代码转换 Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。