1.块作用域和let
问题1:hoist:打乱了程序的正常执行顺序
解决:今后用let代替var声明变量
原理:通过禁止在当前作用域内提前使用未声明的变量,来避免声明提前
强调:如果已经用let声明的变量不能再用var重复声明
问题2:js没有块级作用域,块内的变量即使不执行也会影响块外的变量
块级作用域:程序中的一堆{}之间,成为代码块
js vs java java:三级作用域:全局 函数 块
js 两级作用域 全局 函数,没有块级作用域
解决:用let代替var
规定:let声明的变量仅在当前块内有效
原理:自动在块级作用域位置创建匿名函数自调来划分临时作用域
问题3:原来在for/while/if...内声明的变量,出了结构就不能使用
解决:今后,只要出了结构,还要使用的变量,必须在结构外提前声明
总结:今后所有的变量都要用let声明,而不用var
2.箭头函数
箭头函数:简化回调函数
何时:今后所有的回调函数都可以用箭头函数简化
如何:
1.去function 改箭头
2.如果只有一个参数变量,可省略()
3.如果函数体只有一句话,可以省略{},如果仅有一句return ,则可省略return
箭头函数特点:内容this通用
3.参数增强
Default:(默认值):ES6中,允许为函数的参数列表末尾的几个参数变量,预先定义默认值
function fun(参数1,参数2,参数3=默认值,参数4=默认值){}
调用时,如果传给参数的值有效,就用传入的值,如果没有传入参数或者传入的参数值无效,则用提前指定的默认值
REST:(剩余参数列表):为了代替auguments类数组对象来接受不确定个数的参数值
arguments的问题:
1.不是真正的数组,无法使用数组的API
2.默认只能获取所有参数值,无法仅选取部分参数值
解决:REST
何时:今后都是用rest语法代替arguments
如何:定义函数时,function fun(参数1,参数2,...剩余参数的统称){}
调用时:...剩余参数统称会获得一个数组
function calc(base,...bonus){
return bonus.reduce(
(prev,val)=>prev+val,base
)
}
calc(10000,1000,2000,3000);//16000
SPREAD:(散播): ES6中,为了代替apply,打散数组类型的参数
apply的问题:1.必须传入第一个对象参数,代替this
2.必须将所有参数都放入数组中
解决:spread
何时:今后只要打散数组类型参数时,首选spread
如何:定义函数时,参数变量是分开定义的,调用函数时,可用fun(值1,...arr)
获得数组中的最大值
var arr=[1,2,3,4,5,6];
Math.max(...arr) 相当于 Math.max.apply(null,arr);
4.模板字符串
模板字符串:简化复杂格式的字符串拼接
何时:今后所有的字符串拼接,都用模板字符串代替+
如何:
1.用反引号``包裹整个字符串
2.在模板字符串内,自动支持换行
3.在模板字符串内,支持动态生成表达式的值,要执行的表达式必须用${}包裹
var price=0,count=5;
console.log(
`单价:¥${price.toFixed(2)}
数量:${count}
总价:¥${(price*count).toFixed(2)}`
);
5.解构
解构:简化复杂对象的打散和批量赋值
1.数组解构:等号左右两边都是数组格式。解构时用下标对应值和变量
2.对象解构:等号左右两边都是对象解构。解构时用属性名匹配值和变量
3.参数解构:其实在调用函数时,如果传入的参数值时数组或者对象,也可被解构为单个参数值。用法和数组解构以及对象解构一致
6.class:为了简化面向对象:封装,继承,多态,访问器属性,静态方法
class:集中定义构造函数和原型对象方法的程序解构
为什么:更像封装
何时:只要创建一种新类型,必须先定义class
如何:
class 类型名{
constructor(...){
this.xxx=xxx;
}
原型对象方法(){//类型名.prototype.原型对象方法
}
}
继承:2步
1.在子类型的构造函数中借用父类型的构造函数
如何:super(参数值) super自动指代父类型的构造函数
2.子类型的原型对象继承父类型的原型对象
如何:class 子类型 extends 父类型,不用在Object.setPrototypeof(子类型,父类型);
访问器属性
class 类型名{
constructor(...){
this._age=age;
}
get age(){return this_age}
set age(val){
}
}
类数组对象转为数组:
var args=Array.prototype.slice.call(arguments);
静态方法 static
什么是:不需要创建对象,用构造函数就可以直接调用的方法 Array.isArray(obj)
set集合
元素值不允许重复的集合,专门用于按元素值,直接判断集合中是否存在指定的元素
如何: var set=new Set(凡是可遍历的 都可打散转为set);
得到元素不重复的set类型
将set类型转为数组
var arr=[...set];
var nums=new Set("helloworld");
console.log(nums)//{'h','e','l','o','w','r','d'};
//判断是否含有指定字母
nums.has('o');//true
set集合的其他方法
set.size获取结合中元素的个数
set.has(value)判断集合中是否包含指定元素
set.add(value)添加元素,如果已经存在,则无效
set.delete(value)删除元素
set.clear()清空集合
鄙视:数组去重复且考虑百万级
map集合
什么是:一组键值对儿的集合
何时:代替关联数组使用
如何:var map=new Map();//{}
hash.set(key,value);//hash[key]=value;
var bool=hash.has(key)//hash[key]!==undefined;
for of 遍历
for of 代替for循环遍历
什么是:依次获得数组/类数组对象/集合中每个值
何时:今后只要不关心位置,只关心每个元素值时
如何: for(var value of 数组/类数组对象/集合){}
问题:无法获得位置;必须从头到尾逐个执行;只能从头到尾顺序遍历,不能反向遍历
Symbol
什么是:获得一个不与对象中现有任何属性冲突的唯一属性,定义了Symbol
symbol是第六大原始类型
symbol的值必须通过symbol函数获得
symbol的值作为属性名时,不能用.访问,只能用[]访问
****promises
什么是:解决”callback hell“
为什么:回调函数,层级很可能很深,可读性极差
何时:今后只要多个回调函数必须保证顺序执行时
如何解决callback hell:2步
1. 在前一个函数内return new Promise(callback);
2.在调用前一个函数时,用.then(callback);