ES6
一、变量
1.1 let变量
用于申明变量,用法与var相似,但存在新的个性
个性:
- let所申明的变量,只在以后代码块内无效,防止全局净化
- 没有变量申明晋升
- 暂时性死区,在let命令申明变量前,该变量都是不可用的
- 不容许反复申明
二、常量
2.1 const命令
用于申明常量
个性:
不能够从新赋值
const obj = { name:'alice', age:22}obj.name = 'zhang' //{ name: 'zhang', age: 22 },不报错,因为只扭转了对象的值,没有扭转援用地址
申明的同时必须初始化
const a = 7;
- 暂时性死区
- 不容许反复申明
- 只在以后的代码块内无效
三、解构
3.1 数组解构
从数组和对象中提取值,对变量进行赋值。即只有等号两边的模式雷同,等号左边的值就会一一进行赋值。
let [a,b,c] = [1,2,3]let [a,b,c] = [1,2,3,4] //1 2 3let [a,b,...c] = [1,2,3,4] //1 2 [3,4]let[a,b,c,d,e] = [1,2,3] //1 2 3 undefined undefined//等号右边变量多余,多余的变量会被赋值为undefined//等号左边变量多余,多余的变量会被忽视或者应用...将其整合为一个数组let[a,[b],c] = [1,[2,3],4] //1 2 4let[a,b,c] = [1,[2,3],4] //1 [ 2, 3 ] 4let[a,[b,c],d] = [1,[2,3],4] //1 2 3 4let[a,b,c,d] = [1,[2,3],4] //1 [ 2, 3 ] 4 undefinedlet[a,b=22] = [10] //10 22let[a,b=22] = [10,20] //10 20//如果扭转了默认值,则以扭转后的值为准,若没有扭转,则持续应用默认值
数组嵌套对象
let[a,{name:user}] = ['hello',{name:'tom'}]console.log(a, user)//hello tom
对象嵌套数组
let{test} = {test:[1,2,3]}console.log(test)//[1,2,3]
默认值可为函数
function f(){console.log(111)}let[x=f()] = [1]console.log(x) //1
3.2 对象解构
对象的属性没有秩序,所以变量必须与属性同名,能力取到正确的值
let{name,age} = {name:'tom',age:12}//是let{name:name,age:age} = {name:'tom',age:12}的简写console.log(name,age) //tom 12
//若要批改属性名let{foo:bar}={foo:'ss',bar:'aa'}//将foo改为bar,bar的值为'ss'console.log(bar) //ss
3.3 字符串解构
字符串被转换成一个相似数组的对象
const [a, b, c, d, e] = ‘hello’; //a=h;b=e;c=l;d=l;e=o
对数组的属性解构
let{length:t}='zzzh'console.log(t) //4let{trim}='zzz'console.log(trim === String.prototype.trim) //true//能够解构其原型上的办法let{toString}=trueconsole.log(toString === Boolean.prototype.toString); //true
函数参数解构
function test([a,b]){ return a+b}let res = test([1,2])console.log(res) //3function test({a=3,b=2}){ return a*b}let s = test({a:1})console.log(s) //2
用途:
从函数返回多个值
function foo(){ return[1,2,3]}let[a,b,c] = foo()
替换变量的值
let a=3;let b=4;[a,b]=[b,a];
四、对象扩大
ES6容许间接在对象中写入变量和办法,此时属性名就是变量名,属性值就是变量值
let name = 'tom'let age = 12// let obj = {// name:name,// age:age,// gender:'男',// sayName:function(){// console.log(1111)// }// }let obj = { name, age, gender:'男', sayName(){ console.log(1111) }}
办法的name属性为办法名
function test(){}console.log(test.name) //testlet p = { //test:function(){} test(){ }}console.log(p.test.name) //test
let test = 'hello'let obj = { name:'zhangsan', //test:'hello' test,
[test]:'123'
}
console.log(obj) //{ name: 'zhangsan', test: 'hello', hello: '123' }
- Object.is()用来判断两个值是否相等,与===的不同之处:-0不等于+0,NAN相等
let a = +0
let b = -0
var res = Object.is(a,b) //false
console.log(a===b) //true
let a = NaN
let b = NaN
var res = Object.is(a,b)
console.log(a===b) //false
console.log(res) //true
- Object.assign(target,...,obj)将前面的参数对象合并到target对象中,是一种浅拷贝
let obj1={
name:'tom'
}
let obj2 = {
name:'zhangsan', age:12
}
let obj3 = {
gender:'男', sayName:function(){ }
}
let target = {}
let res = Object.assign(target,obj1,obj2,obj3)
console.log(target)
console.log(res)
/*高低返回统一{
name: 'zhangsan',age: 12,gender: '男',sayName: [Function: sayName]
}*/
本人写assign函数
function myAssign(target,...temp){
temp.forEach(function(item){ for(var key in item){ target[key] = item[key] } }) return target
}
myAssign(target,obj2,obj1,obj3)
console.log(target)
//{ name: 'tom', age: 12, gender: '男', sayName: [Function: sayName] }
- Object.keys(obj) 返回由obj对象的属性名形成的一个数组Object.values(obj) 返回由obj对象的属性值形成的一个数组Object.entries(obj) 返回由obj对象中属性名和属性值组成的数组所形成的数组
let obj = {
name:'ss', age:13, gender:'女'
}
var res = Object.keys(obj)
console.log(res) //[ 'name', 'age', 'gender' ]
var res = Object.values(obj)
console.log(res) //[ 'ss', 13, '女' ]
var res = Object.entries(obj)
console.log(res) //[ [ 'name', 'ss' ], [ 'age', 13 ], [ 'gender', '女' ] ]
## 五、函数扩大- 容许为函数的参数设置默认值(函数的length属性值为未给予默认值的参数个数)- rest参数(...变量名)
function foo(...values){
console.log(values)
}
foo(1,2,3,2,1) //[ 1, 2, 3, 2, 1 ]
- **箭头函数**- ```javascript let test1 = (a,b)=> console.log(a+b) test1(1,2) let test2 = a => console.log(a) test2(1) //参数只有一个时能够省略小括号(),函数体中只有一条语句时能够省略大括号{}
//箭头函数没有本人的this,而是援用内部的this let obj = { name:'tom', sayName(){ console.log(this) } } obj.sayName() //{ name: 'tom', sayName: [Function: sayName] } let obj = { name:'tom', sayName:()=>{ console.log(this) } } obj.sayName() //{} //此时的this指向全局
- 不能作为构造函数
- 没有外部属性arguments
五、数组扩大
扩大运算符(..),rest参数的逆运算
let arr =[1,2,3]console.log(...arr) //1 2 3console.log([...'hello']) //[ 'h', 'e', 'l', 'l', 'o' ],行将字符串转换为数组
Array.from() 能够将类数组对象或可迭代数据转换成数组
let obj = {'0':'hello','1':'world','2':'nice',length:5}console.log(Array.from(obj)) //[ 'hello', 'world', 'nice', undefined, undefined ]
Array.of() 能够将一组值转换成数组
console.log(Array.of(true,true,false)) //[ true, true, false ]console.log(Array.of('hello','nice','world')) //[ 'hello', 'nice', 'world' ]
.find() 参数是一个回调函数,所有数组成员顺次执行此回调函数,直到找到第一个被回调函数筛选出的值(即第一个返回值为true的成员),并返回该值
let arr = [10,2,3,,11]let res = arr.find((item,index,arr)=>{ return item<10})console.log(res) //2//若没有符合条件的值,则返回undefined
.findIndex() 遍历数组,找到第一个被回调函数筛选出的值,并返回该值的索引
let arr = [10,2,3,,11]let res = arr.findIndex((item,index,arr)=>{ return item<10})console.log(res) //1//若没有符合条件的值,则返回-1
.fill() 应用固定的值去填充数组
let arr = []arr.length = 3let res = arr.fill(10)console.log(res) //[10,10,10]console.log(res === arr) //true
- .keys(),values(),entries(),返回一个遍历器对象,可执行for-of命令进行遍历
索引,值,键值对
- .includes() 判断某个数是否存在于数组中,返回一个布尔值
六、Set/Map
6.1 Set
相似于数组,但它的数据汇合是无反复的
//s是Set的实例arr = [1,2,2,1,2,3,4,5]let s = new Set(arr)console.log(s) //Set { 1, 2, 3, 4, 5 }arr = [...s] //将set对象转换为数组console.log(arr) //[1,2,3,4,5]
- 属性:
.size Set实例中的成员总数
- 办法:
.add(value) / .delete(value) / .clear() / .has(value) set成员中是否蕴含该值 / .forEach() / .keys(),values(),entries()
s = [1,1,1,2,3,4,1]console.log([...new Set(s)]) //去重,参数能够为具备iterator接口的其余数据结构
6.2 Map
Map相似于对象,也是键值对的汇合,然而其键的数据类型不仅限于字符串
//能够接管数组作为参数let map = new Map([ ['name', '张三'], ['title', 'Author'] ]);console.log(map) //Map { 'name' => '张三', 'title' => 'Author' }map.set('name','alex')map.set('age',12)console.log(map.has('age'))map.delete('name')
- 属性:
.size Map构造中的成员总数
- 办法:
.set(key,value) / .get(key) / .delete(key) / .clear() / .has(key) Map对象中是否蕴含该键 / .forEach() / .keys(),values(),entries()
6.3 Iterator(遍历器)
Iterator是一种接口,为各种不同的数据结构提供对立的拜访机制。任何只有被部署Iterator接口的数据结构都能够实现遍历操作。
作用:
- 为各种数据结构提供了对立的、简便的拜访接口
- 使得数据结构的成员可能按某种秩序排列
供es6新推出的遍历命令for...of生产
let arr = [1,2,3,4,5]let keys = arr.keys()for(let key of keys){ console.log(key)}
- 具备Iterator接口的数据结构:
Array、Map、Set、String、TypeArray、函数的arguments对象、NodeList对象
next()
let s = new Set([10,2,2,2,3,1])let values = s.values()console.log(values.next()) //{ value: 10, done: false }false代表没有完结console.log(values.next()) //{ value: 2, done: false }console.log(values.next()) //{ value: 3, done: false }console.log(values.next()) //{ value: 1, done: false }console.log(values.next()) //{ value: undefined, done: true }
七、Class
ES6的class中的绝大多数性能ES5都能做到,新的class写法只是让对象原型的写法更加清晰更像面向对象编程的语法。
class Animal{ //构造函数 constructor(name){ this.name = name //类的实例属性定义在构造函数当中 } //在类中能够间接定义方法,这些办法都定义在类的prototype属性下面,都会被实例继承。 toSay(){ console.log('实例办法') } //静态方法不能被实例调用(继承),只能通过类调用 //静态方法中的this指的是类,而不是实例 static mySay(){ console.log('静态方法') }}let cat = new Animal('tom')cat.toSay()Animal.mySay()console.log(cat)//动态属性只能通过此种办法进行定义Animal.sound = 'miao'console.log(Animal.sound) //miao//能够通过Object.assign()办法向类的原型中增加办法Object.assign(Point.prototype, { toString(){}, toValue(){} });
继承
class Animal{ constructor(name){ this.name = name; } say(){ console.log('say') } static sayMy(){ console.log('sayMy') }}class Dog extends Animal{ constructor(name,age){ //此时的super()相当于Animal.prototype.constructor.call(this),即调用父类的构造函数(this指向的的是Dog,返回的是Dog的实例) //此时的super为函数 super(name); this.age = age; } Dogsay(){ //super指向父类的原型对象,相当于super.say.call(this),this指向Dog //此时的super为对象 super.say() } static DogsayMy(){ //super指向父类 super.sayMy() }}let dog = new Dog('wang',6)dog.say()dog.Dogsay()Dog.sayMy()Dog.DogsayMy()console.log(dog)console.log(Dog.__proto__ === Animal)//子类的__proto__属性示意构造函数的继承,指向父类console.log(Dog.prototype.__proto__ === Animal.prototype)//子类的prototype.__proto__属性示意办法的继承,指向父类
八、Promise
Promise是一个容器,寄存着将来将要完结的某个事件(通常是异步操作)的后果。同时,Promise也是一个对象,能够获取异步操作的音讯。它能够将异步操作以同步操作的流程表达出来。用于解决异步,优化异步。
promise的参数是一个函数,函数的参数别离为resolve和reject:
- resolve函数在异步操作胜利时调用(promise对象的状态pedding-->fullfilled),会将异步操作的后果,作为参数传递给回调函数
- reject函数在异步操作失败时调用(promise对象的状态pedding-->rejected),会将异步操作报出的谬误,作为参数传递给回调函数
通过then办法和catch办法(或者then办法的第二个参数,个别不应用)别离指定两个状态的回调函数
let p = new Promise((resolve,reject)=>{ $.ajax({ url:'http://39.105.67.242:5588/orde/findAll', method:'get', success:function(res){ resolve(res) }, error:function(e){ reject(e) } })})p.then((res)=>{ console.log(res)}).catch((e)=>{ console.log(e)}).finally(()=>{ //不论Promise的状态最初如何,都会执行此回调函数 console.log('完结')})
Promise.all()
//参数为一个数组,p1,p2,p3都为Promise实例var p = Promise.all([p1,p2,p3])
只有p1,p2,p3的状态都转变为fullfilled,p的状态能力转变为fullfilled。此时p1,p2,p3的返回值组成一个数组,传递给p的回调函数。p1,p2,p3中只有有一个状态转变为rejected,p的状态就转变为rejected,此时第一个状态变为rejected的实例的返回值被传递给p的回调函数。
Promise.race()
//参数为一个数组var p = Promise.race([p1,p2,p3])
只p1,p2,p3中有一个实例的状态被扭转,p的状态就会被扭转。率先扭转状态的实例的返回值被传递给p的回调函数。
九、Generator
Generator是一个状态机,封装了多个外部状态。执行Generator函数会返回一个遍历器对象,能够顺次遍历Generator函数外部的每一个状态。
能够将异步操作同步化。
//function与函数名之间加*function* test(){ yield 'hello' yield 'world' yield 'nice' return 'yes'}let res = test() //返回一个迭代器对象console.log(res.next()) //{ value: 'hello', done: false }console.log(res.next()) //{ value: 'world', done: false }console.log(res.next()) //{ value: 'nice', done: false }console.log(res.next()) //{ value: 'yes', done: true }
利用:
let axios = require('axios')function* main() { var result = yield request("http://39.105.67.242:5588/customer/findAll"); console.log(result.data);}function request(url) { // response参数当做上一个yield表达式的返回值 //.then代表异步申请胜利 axios.get(url).then(function(response){it.next(response);}); //it.next(response)执行的是result=response以及前面的输入语句}var it = main();//返回迭代器对象it.next();//执行yield表达式里的request函数
十、Async
将异步操作同步化
let axios = require('axios')//function前加asyncasync function foo(){ //只有以后的异步操作实现后,能力执行上面的输入操作 let customers = await axios.get("http://39.105.67.242:5588/customer/findAll"); console.log("customers:",customers.data.data[0].id); } foo();
十一、模块化
CommonJS API将通过定义解决许多常见应用程序需要的API来填补javascript标准没有定义用于构建更宽泛应用程序的规范库的毛病,最终提供与Python、Ruby和Java一样丰盛的规范库。其用意是应用程序开发人员可能应用CommonJS API编写应用程序,而后在不同的JavaScript解释器和主机环境中运行该应用程序。
11.1 模块化作用域
每个文件就是一个模块,有本人的作用域。在一个文件外面定义的变量、函数、类,都是公有的,对其余文件不可见.
全局属性
global.warn = true
- 公有属性
11.2 模块的导入导出(模块交互)
CommanJS
导出(定义模块)
//module变量代表以后模块,其exports属性是对外的接口module.exports.a = a
导入(模块加载)
let b = require('模块门路')console.log(b.a)
es6
导出
export default xx
导入
import xx from ''
11.3 模块对象
- module.id 模块的辨认符,通常是带有绝对路径的模块文件名。
- module.filename 模块的文件名,带有绝对路径。
- module.loaded 返回一个布尔值,示意模块是否曾经实现加载。
- module.parent 返回一个对象,示意调用该模块的模块。
- module.children 返回一个数组,示意该模块要用到的其余模块。
- module.exports 示意模块对外输入的值。
11.2 path模块
用于文件门路
装置path模块
npm install path
引入path模块
var path = require('path')
- basename('') 返回文件名
- dirname('')返回目录名
- extname('')返回文件扩展名
let path = require('path')console.log(path.basename('./a.js')) //a.jsconsole.log(path.dirname('d:/briup/4-es6/0821/a.js')) //d:/briup/4-es6/0821console.log(path.extname('./a.js')) //.js
11.3 querystring模块
把对象转换成查问字符串
let res = querystring.stringify(obj)
把查问字符串转换成对象
let str = querystring.parse(res)
十二、npm
Npm是使Js开发者可能更不便的分享和复用以及更新代码,被复用的代码被称为包或者模块,一个模块中蕴含了一到多个js文件。在模块中个别还会蕴含一个package.json的文件,该文件中蕴含了该模块的配置信息。一个残缺的我的项目,须要依赖很多个模块。
> npm init
创立配置文件package.json
> npm init -y
创立默认配置文件
> npm install npm@latest -g
更新npm(npm会随着node一起被装置到本地)
> npm install -g cnpm --registry=https://registry.npm.taobao.org
装置淘宝镜像,放慢下载速度
> npm install + '依赖的名字'
装置模块,装置模块时,默认会将所装置的模块写入到package.json中的dependencies属性中。如果想要仅在以后模块中应用某个第三方模块,就能够应用npm install的默认装置,默认装置即是本地装置;如果想要在命令行中应用模块,就须要进行全局装置。
> npm install
装置所有我的项目依赖的模块(依赖关系在配置文件中已存在)
> npm update <module_name>
更新模块
> npm uninstall -g <package_name>
从node_modules中删除不须要的模块
> npm uninstall –save -g <package_name>
不仅删除node_modules中的依赖,还须要删除package.json中的信息,能够应用—save参数
- -g 全局装置,一处装置处处应用,不加-g,即为部分装置,只在以后门路内无效
十三、babel
babel用于将es6转换成浏览器可辨认的es5(因为浏览器只能辨认一部分es6的语法)
> babel a.js//将a.js代码转换为es6
> babel a.js --out-file test.js //将a.js的代码转换成es5并导入到test.js文件中
babel src --out-dir srcc//将src文件夹中所有的文件转换为es5并导入到srcc文件夹下