根据慕课网记录(感觉还是阮老师的很好理解。http://es6.ruanyifeng.com/#README)
let和const
let
- 作用类似于var,用来声明变量。
- ES6之前有两个作用域
- 函数作用域
- 全局作用域
- 块作用域{}(ES6新增)
- let声明的变量只在自己的块作用域中有效
function test(){
for(let i=1;i<3;i++){
console.log(i);
}
console.log(i);(报错,脱离块作用域)
}
test()
let a=1;
let b=2;
- 块作用域:如果代码用大括号包起来的,就是块作用域了
- 报错:ReferenceError引用错误?为什么不是未定义undefined呢?
- 因为ES6强制开启严格模式(”use strict”;)
- 使用let不允许在相同作用域内变量重复定义变量
const
function last(){
const PI=3.1415926;
const k={
a:1
}
k.b=3;
console.log(PI,k);
}
- 一旦声明,常量的值就不能改变。
- 声明时必须赋值
- k为对象(引用类型:返回对象存储位置指针),指针不变,但是对象本身是可以变化的
解构赋值(destructuring assignment)
注意左右两边格式的对应
- 数组解构赋值
- 函数参数解构赋值
- 对象解构赋值
- 布尔值解构赋值
- 数值解构赋值
- 字符串解构赋值
数组解构赋值
{
let a,b,rest;
[a,b]=[1,2]; //等价于let a = 1;let b = 2;
console.log(a,b);
}
输出1 2
可以使用……
{
let a,b,rest;
[a,b,...rest]=[1,2,3,4,5,6];
console.log(a,b,rest);
}
输出:1 2 (4) [3, 4, 5, 6]
解构赋值右侧和左侧不必一一对应。左侧多余赋值为undefined,右侧多余赋值会忽略
{
let a,b,c,rest;
[a,b,c=3]=[1,2];
console.log(a,b,c);
}
解构赋值用途(简化代码)
变量交换
{
let a=1;
let b=2;
[a,b]=[b,a];
console.log(a,b);
}
函数返回数组,直接进行操作
ES5,用一个临时变量来接收返回值,然后通过索引来查找,进而赋值
{
function f(){
return [1,2]
}
let a,b;
[a,b]=f();
console.log(a,b);
}
选择性接收数组赋值
{
function f(){
return [1,2,3,4,5]
}
let a,b,c;
[a,,,b]=f();
console.log(a,b);
1 4
}
当我们不知道数组长度时,只想取得一个元素时
{
function f(){
return [1,2,3,4,5]
}
let a,b,c;
[a,,...b]=f();
console.log(a,b);
1 (3) [3, 4, 5]
}
“链式“解构赋值
{
let f,s,a;
a = [f,s] = [1,2,3,4];
console.log(a,f,s);
{
let f,s,a;
a = [f,s] = [1,2,3,4];
console.log(a,f,s);
}
数组嵌套
{
let f,s,a,d,e;
a = [f,s,[d,e]] = [1,2,[3,4]];
}
对象解构赋值
{
let a,b;
({a,b}={a:1,b:2})
console.log(a,b);
}
输出1 2
{
let o={p:42,q:true};
let {p,q}=o;
console.log(p,q);
}
默认值赋值处理
{
let {a=10,b=5}={a:3};
console.log(a,b);
}
JSON对象嵌套赋值
{
let metaData={
title:'abc',
name: '王八',
test:[{
title:'test',
desc:'description'
}]
}
let {title:esTitle,test:[{title:cnTitle}]}=metaData;
console.log(esTitle,cnTitle);
}
正则扩展(regular expression)
新增特性
- 构造函数变化
- 正则方法的扩展
- u修饰符(Unicode)
- y“粘连”(sticky)修饰符
- s修饰符
字符串对象的4个使用正则表达式的方法: match(),replace(),search(),split()这四个方法全部调用RegExp的实例的方法。
构造函数
{
// #ES5构造函数#
let regex = new RegExp('xyz', 'i'); //第一个参数是字符串,第二个是修饰符(忽略大小写)
let regex2 = new RegExp(/xyz/i); //第一个参数是正则表达式,不接受第二个参数,否则会报错(正则表达式直接量定义//修饰符)
console.log(regex.test('xyz123'), regex2.test('xyz123'));
console.log(regex.test('xyZ123'), regex2.test('xyZ123'));//输出相同
// #ES6构造函数#
let regex3 = new RegExp(/abc/ig, 'i');
console.log(regex3.flags); //原有正则对象的修饰符是ig,它会被第二个参数i覆盖 flags新增,用来获取正则表达式的属性
}
y修饰符
{
// y修饰符
let s = 'bbbb_bbb_bb_b';
var a1 = /b+/g;
var a2 = /b+/y;
console.log(a1.exec(s), a2.exec(s)); // ["bbbb"],["bbbb"]
console.log(a1.exec(s), a2.exec(s)); // ["bbb"],null
console.log(a1.sticky, a2.sticky); //表示是否开启了粘连模式
}
y修饰符的作用与g修饰符类似,都是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始
u修饰符
点(.)字符不能识别码点大于0xFFFF的Unicode字符(两个字节),必须加上u修饰符(ES5,换行符,回车符,行分隔符,段分隔符)。
{
// #正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是行终止符(line terminator character)除外
// U+000A 换行符(\n)
// U+000D 回车符(\r)
// U+2028 行分隔符(line separator)
// U+2029 段分隔符(paragraph separator)
// 只是一个提案目前还不支持
// let reg=/test.go/s;
// console.log(reg.test('test\ngo'));
// console.log(reg.test('test\ngo'));
console.log('s变通方法',/foo.bar/.test('foo\nbar'));
console.log('s变通方法',/foo[^]bar/.test('foo\nbar'));
}
字符串扩展(完善了Unicode处理问题)
- Unicode表示法
- 遍历接口
- 模板字符串
- 新增10种方法(包括ES7提案)
- 补丁库babel-polyfill
Unicode表示法
{
console.log('a',`\u0061`);
console.log('s',`\u20BB7`);
console.log('s',`\u{20BB7}`);(加{})
}
{
// ES5
let s='��'; //大于两个字节,处理成四个字节,在计算长度时(两个字节就是一个长度)
console.log('length',s.length); //2
console.log('0',s.charAt(0)); //取第一个位置的一个字符 乱码
console.log('1',s.charAt(1)); //取第一个位置的二个字符 乱码
console.log('at0',s.charCodeAt(0));//取第一个位置的一个Unicode码值,charCodeAt只取两个字节
console.log('at1',s.charCodeAt(1));
// ES6
let s1='��a';
console.log('length',s1.length);
console.log('code0',s1.codePointAt(0)); //第一个字符 (10进制) 自动取四个字节
console.log('code0',s1.codePointAt(0).toString(16)); // 第二个字符(16进制)
console.log('code1',s1.codePointAt(1));
console.log('code2',s1.codePointAt(2));
}
{
// ES5
console.log(String.fromCharCode("0x20bb7"));
// ES6(能处理大于0XFFFF的字符)
console.log(String.fromCodePoint("0x20bb7"));
}
// 字符串遍历
{
let str='\u{20bb7}abc';
// ES5遍历
for(let i=0;i<str.length;i++){
console.log('es5',str[i]);
}
// ES6遍历
for(let code of str){
console.log('es6',code);
}
}
{
let str="string";
console.log('includes',str.includes("c"));
console.log('start',str.startsWith('str'));
console.log('end',str.endsWith('ng'));
}
{
let str="abc";
console.log(str.repeat(2));
}
{
let name="list";
let info="hello world";
let m=`i am ${name},${info}`;
console.log(m);
}
{
console.log('11'.padStart(20,'0'));
console.log('1'.padEnd(2,'0'));
}
{
let user={
name:'list',
info:'hello world'
};
console.log(abc`i am ${user.name},${user.info}`);
function abc(s,v1,v2){
console.log(s,v1,v2);
return s+v1+v2
}
}
{
console.log(String.raw`Hi\n${1+2}`);
// \n换行符没有生效,转义
console.log(`Hi\n${1+2}`);
// \n换行符生效
}
数值扩展
{
console.log('B',0B111110111);
console.log(0o767);
}
{
console.log('15',Number.isFinite(15));
console.log('NaN',Number.isFinite(NaN));
console.log('1/0',Number.isFinite('true'/0));
console.log('NaN',Number.isNaN(NaN));
console.log('0',Number.isNaN(0));
}
{
console.log('25',Number.isInteger(25));
console.log('25.0',Number.isInteger(25.0));
console.log('25.1',Number.isInteger(25.1));
console.log('25.1',Number.isInteger('25'));
}
{
console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);
console.log('10',Number.isSafeInteger(10));
console.log('a',Number.isSafeInteger('a'));
}
{
console.log(4.1,Math.trunc(4.1));
console.log(4.9,Math.trunc(4.9));
}
{
console.log('-5',Math.sign(-5));
console.log('0',Math.sign(0));
console.log('5',Math.sign(5));
console.log('50',Math.sign('50'));
console.log('foo',Math.sign('foo'));
}
{
console.log('-1',Math.cbrt(-1));
console.log('8',Math.cbrt(8));
}