1.let
声明变量,类似 var,但是相比较var,还是有很大的不同。
- 不允许重复声明
var如果重复声明,则后面的声明会覆盖前面的声明。而运行到let的重复声明时,浏览器会报错,提示说该变量已经被声明。
- 必须先声明后使用(暂存死区)
var具有变量提升的效果,即如果在声明之前使用,该变量的值为undefined,而let必须声明再使用,否则会报错。
在代码块内,在let声明变量之前,该变量都是不可用的。在语法上,称为“暂时性死区”。
- 支持块级作用域:一对 {} 产生一个块,在 {} 内部就会形成一个独立的作用域:块作用域。
for (var i=0; i<5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局都只有一个变量i。每一次循环,变量i的值都发生改变。而循环内的i都指向全局的i,导致运行时输出的最后一轮的i的值,也就是5个5。
for (let i = 0; i<5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
变量i是let声明的,当前的i只在本轮循环内有效,所以每一次循环的i其实都是一个新的变量。
另外,for循环还有一个特别之处,就是设置循环变量那部分是一个父作用域,而循环体内部的一个单独的子作用域。上面代码正确运行,输出5次,分别为1,2,3,4,5。
3. const
常量声明
- 支持块作用域
- 先声明后使用
- 不允许重复声明
- 常量声明一定需要初始化-声明之后立马赋值
- 推荐:常量名称全大写
const实际保证的是变量指向的内存地址不得改动。对于简单型数据,值就保存在变量指向的那个内存地址中,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,无法保证它指向的数据结构是不是可变的。
对象冻结
如果想要冻结对象,应该使用object.freeze方法。但是有局限性:该方法只能冻结对象内的第一层属性,也就是说如果要冻结的对象有属性值为对象,那这个作为属性值的对象是无法进行冻结的。
要想达到深度冻结,则需要运用递归将对象的属性也进行冻结。
var deepFreeze = (obj) =>{
Object.freeze(obj);
Object.keys(obj).forEach((key,i) =>{
if(typeof obj[key] === 'object'){
deepFreeze(obj[key]);
}
})
}
4. 解构赋值
对右侧的数据进行解构(解析解构),把值对应的一一赋值给左侧的变量
- 数组解构赋值
- 左侧是 [] ,值是一一(位置)对应的。
- 如果解构不成功,则变量的值为undefined
等号的右边的数据具有Iterator接口,都可以采用数组形式解构赋值;
解构赋值允许指定默认值,ES6中使用严格相等符(===),判断一个位置是否有值,如果一个数组的成员不严格等于undefined,默认值不会生效。默认值可以引用解构赋值的其他已被声明的变量。
对象解构赋值
- 左侧是{},key一一对应。左侧变量的名称和右侧对象中属性的名称是有关联的(必须名称相同)
- 与数组解构赋值一样,也可以指定默认值
- 如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错
let obj = {x:1,y:2};
let {y, x} = obj;
console.log(x, y); //此时x为1,y为2;
- 如果结构对象时,已经存在同名变量,则可以解构时给左侧变量取别名。如下所示:
let x = 100;
let obj = {x:1,y:2};
let {y, x:mx} = obj;//此时mx为x的别名
console.log(x, mx, y); //mx的值为1
5. 字符串扩展
字符串解析
因为新增的一些中文字符,在编码中会采用五位来表示。而解析是会将实际为一个字符的编码按四位一解析的原则,解析成两位。解决办法:将此类方法用{}括起来
console.log( '\u{1F470}' );
字符串长度问题
因为unico字符增加,而length方法没有同步更新。所以使用length获取字符长度会有问题
console.log( '\u1F470'.length );
//会将0作为一个字符编码,0前面4位字符作为字符编码。
//length结果为2,实际上为1
字符串码点获取方式
es6推荐使下方方法获取字符编码点
console.log( '\u{1F385}'.codePointAt(0) );
console.log( String.fromCodePoint(127877) );
字符串新增方法
- str.repeat(num)
将str重复num次
- at(num)
与charAt()作用类似,是为了弥补charAt()不能识别大于0xFFFF码点的缺陷
- include(str)/startsWidth(str)/endsWidth(str)
以上三个方法都是用来判断字符串中是否含有另一个字符串。includes()表示是否找到str;startsWidth(str)表示是否在字符串的首部找到了str;endsWidth(str)表示是否在字符串的尾部找到了str
- padStart()/padEnd()
字符串补全功能。padStart()用来首部补全,padEnd()用来尾部补全。接收两个参数,第一个为补全的最小长度,第二个为用来补全的字符串
模板字符串
- 使用方法:将字符串写在“里
- 允许多行并保留编辑格式(缩进和换行会予以保留)
- 支持内嵌表达式:语法:${表达式}
6.数字扩展
- 2进制:0b/0B 开头 Binary【es6新增】
- 8进制:0o/0O 开头 Octal【es6新增】
- 10进制:1-9的数字开头 Decimal
- 16进制:0x/0X 开头 Hexadecimal
- Number.isFinite() 用来判断一个数字是否是有限的
- Number.isInteger() 用来判断一个数字是否是整数,注意3.0和3的判断结果都为整数
7. 数组扩展
- 扩展运算符(…)
- 定义:将一个数组转为用逗号分隔的参数序列
- 可以用来函数调用时转换参数
- 扩展运算符后面还可以放置表达式
- 后接空数组,则无任何实际作用
- 可将字符串转换成数组
- 可将任何有迭代器的对象转换成数组
Array.from()
- 将类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)转换成数组。
可接受三个参数:a.要转换的数据 b.数据筛选条件,类似于map操作 c.可以作为第二个参数中this的指向
Array.of() 用于将一组参数,转换为数组。主要是解决 原来 数组中遗留一个 bug。 当我们使用new Array方式来创建数组的时候,如果参数有且仅有一个并且是数字的时候,该参数不在是数组的值,而是数组的长度
var arr2 = new Array(5);
console.dir(arr2);//数组长度为5,内容无
console.dir(arr2[0]);
var arr3 = Array.of(5);//数组长度为1,第0位内容为5
console.dir(arr3);
- .find()
查找满足条件的第一个元素,参数是callback
var arr = ['张三','李四','王五'];
console.log( arr.find( function(item) {
// 循环数组,把当前的循环值作为参数传递给item,
//同时执行该函数,根据该函数的返回来确定是否找到或者继续续向后查找
return true;
} ) );
10..findIndex() 用法与.find类似,只是返回值为找到的元素的下标
11. .fill(val,startPosition,endPosition) 数组填充,第一个参数为填充内容,第二位为填充开始位置,第三位为结束位置(不包括结束位置)