一新的数据类型:
1、let: 特点:
1-1、存在块级作用域;
1-2、暂时性死区;
1-3、同一个作用域内变量不可重复声明;
1-4、不存在变量提升,使用前必须说明。
**2、const **:特点:
2-1:具备let有的特点;
2-2:变量声明时必须赋值;
2-3:变量可读不可写;
3、Symbol
3-1:Symbol()函数的返回值是唯一的,
3-2:利用Symbol函数的返回值,作为对象的属性,可保证属性的键是唯一的,是该数据类型的唯一作用;
3-3:Symbol()函数的参数只能是字符串或者不传,不传参数默认为undefined;
3-4:symbol.for()参数只能是字符串,参数一样返回的值是全等的:如果把一个对象做为参数,此时存在对象隐式调用toString方法。
console.log(Symbol('a')!=Symbol('a'));//false
let key=Symbol.for(undefined)
let key2=Symbol.for();
console.log(key===key2)//true
console.log(Symbol.for({})===Symbol.for({}))//true
console.log(Symbol.for({})===Symbol.for('[object Object]'))//true
4、map :
4-1、保存的是键值对,键和值可以是任何数据类型;键值唯一,否则后面的会覆盖前面的。
4-2、Map构造函数接收的参数,是可迭代对象,默认是udefined,而且这可迭代对象的元素也必须是可迭代的
var map=new Map([[1,1],[2,2]])
map.set(undefined,2)
map.set(undefined,null)
console.log(map);
// new Map(1,2)//参数不可迭代
// new Map([1,2])//参数元素不迭代
// new Map('abc')//参数元素不迭代
4-3、常用方法:增删改查/清空set(key,value)、get(key),delete(key),has(key),clear();
4-4、遍历方法:keys、values,entries、 for...of
**5、set **
5-1、可以存放任何数据类型,元素唯一
5-2、Set是可迭代对象,默认是udefined。
5-3、常用方法:增删改查/清空add(value)、delete(key),has(key),clear()
5-4、遍历方法:keys、values,entries、 for...of
6、weakMap:
6-1:weakMap存放键值对,键必须是对象,值可以是任何数据类型。
6-2:weakMap的键是对象的弱引用,对象的引用不在引用计数之内,随时都会被GC回收。
6-3、常用方法:增删改查/清空set(key,value)、get(key),delete(key),has(key),clear();
**7、waekset **
7-1:waekset元素必须是对象
7-2:weakMap元素是对象的弱引用,对象的引用不在引用计数之内,随时都会被GC回收。
7-3、增删改查/清空add(value)、delete(key),has(key),clear()
**8、proxy **
8-1:代理对象,实现对象操作的拦截
8-2:接受2个对象参数,参数1被代理对象,参数2拦截操作对象handler,该对象的属性是操作拦截方法,返回代理对象,
8-3:handler对象是常用方法get(target,key,proxy)、set(target,key,value,proxy);
9、reflect
9-1:是js的内置对象,只要静态方法;取代Object的一些静态方法
9-2:常用方法:get(target,key,receiver)、set(target,key,value,receiver)
10、class
10-1:class作为构造函数的语法糖;默认提供一个constuctor构造函数;
10-2:class内部的方法,不能用function关键字定义方法,方法与属性之间不能用逗号;
10-3:可以提供extends 关键字实现类的继承;
10-4:如果子类显示声明构造函数,必须在使用this关键字之前,显示调用super()方法实例化父类;
10-5:所有的方法都是在原型链上。
10-6:如果父类的属性和子类重复,子类覆盖父类。
10-7:子如果要调用与父类重名的方法必须通过super关键字。
class Wuzai {
constructor(name) {
this.name =name;
this.age=22;
}
printName() {
console.log(this);//qige
}
}
// 继承Wuzai
class Qige extends Wuzai {
constructor(name) {
super('wuzai') //必须显示调用
this.name = name;
}
printName() {
console.log('from child::', this.name);
console.log('from parent::',super.age);
super.printName();//调用父类的原型方法
}
// var good='error'//语法错误
// function test2(){}//语法错误
}
var qige = new Qige('qige');
11、promise 11-1、promise构造函数接受一个方法作为参数,该方法接受2个可传方法(resolve,reject)参数。返回一个promise对象。
11-2、promise的状态不可逆,pending->fulfill,pending->reject。
11-3、then方法返回一个新的promise对象。
11-4、上次resolve,reject方法的返回值,作为下次then方法的参数方法resolve,reject的的参数。
11-5、异常冒泡机制,如果有下次的reject方法就把错误信息传给他,执行该方法,如果没有就执行catch方法,catch方法的返回值作为下次的成功回调参数。如果不提供catch 方法,就抛出异常
var promise = new Promise((resolve, reject) => {
resolve('第一个resolve')
});
promise.then(res => {
console.log(res);//第一个resolve
console.log(a);
}).then(null, err => {
console.log(err);//Reference Error
console.log(a);
}).then().catch(err=>{
console.log(err);//Reference Error
return '错误被捕获'
}).then(res => {
console.log(res);//错误被捕获
})
二新的语法:
1、async/await
1-1:函数内部有await 关键字函数必须显示声明async;
1-1:关键字async声明的函数返回的是一个promise对象 return 'abc' 等价于Promise.resolve('abc');如果函数的内部抛异常返回Promise.reject(err);
var promise = new Promise((resolve, reject) => {
setTimeout(resolve.bind(null,'第一个resolve'),300)
});
async function getResource(){
var result;
await promise.then(res=>result=res)
console.log(result);//第一个resolve
}
getResource();
async function getResource2(){
return 100
}
getResource2().then(res=>console.log(res));//100
async function getResource3(){
console.log(a);
return 100
}
getResource3().then(res=>console.log(res));Reference Error
2、拓展运算符(...) reset
2-1:作为形参数,把剩余的参数放到数组里面,只能放在参数列表的最一位;
2-2:作为实参:把数组里面的元素,拆分传参;
function reset1(...args){
console.log(args);//[1,2,3]
reset2(...args,6);
}
function reset2(a,b,c,d){
console.log(a);
console.log(b);
console.log(c);
console.log(d);
}
reset1(1,2,3)
2-3:数组,对象合并:
console.log([...[1,2,3],4,5,6]);//[1,2,3,4,5,6]
var obj={a:'A',b:'B'}
console.log({...obj,c:'C'});{a:'A',b:'B',c:'C'}
3、解构赋值
3-1、解构赋值是按结构拆分,赋值给变量:
3-2、实参多,变量少,叫不完全解构,忽略多余的实参;
3-3、变量多,实参少,叫解构失败,多余的变量默认为undefined;
var obj = { a: 'A', b: 'B',g:{f:'F'}};
var arr = [1, 2, 3,[[4],5]];
let { b=10, a,g:{f}} = obj,
[c=1, d, e,[[c1],c2]] = arr;
console.log(a, b, c, d, e,f,c1,c2);
4、函数默认参数:
function reset(a=10,b=12){
console.log(a,b);
}
reset(1,2,3)
5、箭头函数:
5-1、函数内部没有argument对象;
5-2、函数内部没有自己this对象,所以不能使用new 操作符执行,所以也不能通过call、apply、bind改变内部this的指向;
5-3、函数内的this指向,指向所在作用域的对象;
5-4、语法:
参数:如果参数的个数不是1个,参数的括号必须加上。
函数体:如果只要一条执行语句,可以省略花括号,而且该执行语句的结果会作为返回值,如果有多条执行语句,必须加上花括号,默认返回undefined。
6、for...of:迭代实现了 [Symbol.Iterator] 方法的对象
7、对象简写:属性名和键一样,写一个即可
8、对象方法简写:去掉function关键字
三其他
1、迭代器:
1-1:迭代器是一个包含next 方法的对象;
1-2:next方法返回一个对象{value,done},done为true时表示生成器函数执行完毕,或者可迭代对象迭代完毕。
2、生成器函数: * 标识符/ yield 关键字
2-1:* 标识符阻止函数同步执行,返回一个迭代器对象,通过next方法驱动函数内部的语句执行。
2-2:yield 关键字阻止语句执行,并返回关键字后面的值。
function* generator(){
console.log('start....');
for (let i = 0; i < 2; i++) {
//yield i
}
console.log('end....');
}
var iter=generator();
执行generator函数start....并没有打印,证明* 标识符阻止函数同步执行的功能。
3、模块化
1、ES6模块:在ES6中独立的文件就是一个模块,模块的是一个独立的作用域,该作用域内部的变量,对外部部可见。
2、通过export关键字按需暴露出模块内的接口(变量);
3、外部模块通过import关键字按需引入接口;
export {print,obj,qige}
export default class Good{}
import * as 变量名 from 'path'
import good, {print,qige,obj} from './ES6.js'
4、export defualt 暴露出的接口在外部需要一个变量来接收,而且只能放在import关键字的后面
5、外部导入的变量名必须与非默认导出的变量名一致,顺序无关,类型解构赋值
6、ES6模块化与commonJs模块化的区别:
1、ES6导出的是变量值的引用,commonJs导出的是对象的浅拷贝
2、ES6导出模块是编译时导出,commonJs时运行时导出;
3、ES6模块导出的变量外部模块不可以修改,ES模块导出的变量外部模块可以修改;
4、ES6模块import是异步加载模块,commonJs模块require是同步加载模块。
ES6导出的模块不是对象,它的对外接口只是一种静态定义,在代码编译阶段就能够确定。commonJs到出的是对象,对象必须在代码运行时才会存在。