ECMAScript6扩展

快速导航

新增声明变量

  • let

let声明的变量只在自己的块作用域内有效,即大括号{}括起来的。不能重复声明。

  • const

    const声明的数值类型不能被修改,但引用类型除外,注意下面的k是对象,对象是引用类型,引用类型最后返回的是对象中存储的那个指针,也就是说下面的k指向的是存储中的指针,而指针是不变的,变的是对象的值。

  1. function last(){
  2. const PI=3.1415926;
  3. PI = 33 //报错
  4. const k={
  5. a:1
  6. }
  7. k.b=3; //正确
  8. console.log(PI,k);
  9. }

解构赋值

适用于变量交换

数组解构赋值

  1. {
  2. let a,b,reset;
  3. [a,b] = [1,2];
  4. console.log(a,b); //1 2
  5. }
  6. {
  7. let a,b,reset;
  8. [a,b,...reset] = [1,2,4,5,6,7];
  9. console.log(a,b,reset); //1 2 [4,5,6,7]
  10. }

对象解构赋值

  • 一般的对象解构赋值
    1. {
    2. let a,b;
    3. ({a,b} = {a:1,b:2})
    4. console.log(a,b); // 1 2
    5. }
  • 带有默认值的对象解构赋值
    1. {
    2. let {a=10,b=5} = {a:3}
    3. console.log(a,b); // 3 5
    4. }
  • 嵌套的对象解构赋值
    1. {
    2. let metaData = {
    3. title:'abc',
    4. test:[{
    5. title:'标题',
    6. des:'description'
    7. }]
    8. }
    9. let {title:enTitle,test:[{title:cnTitle}]} = metaData;
    10. console.log(enTitle,cnTitle);//abc 标题
    11. }

扩展系列

正则表达式扩展

  • 构造函数 ES5声明对象 情况一

第一个参数是字符; 第二个是修饰符

  1. let regex = new RegExp('xyz', 'i');
  2. console.log(regex.test('xyz123'), regex.test('xyZ123')); // true true
  • 构造函数 ES5声明对象 情况二

第一个参数是正则表达式; 但是此时不接受第二个参数是一个修饰符,否则会报错

  1. let regex2 = new RegExp(/xyz/i); // 正确
  2. let regex3 = new RegExp(/xyz/i, 'i'); // 错误;Uncaught TypeError: Cannot supply flags when constructing one RegExp
  3. console.log(regex2.test('xyz123'), regex2.test('xyZ123')); // true true
  • 构造函数 ES6中的声明对象

ES6改变了此行为,第一个参数是正则表达式,第二个参数也可以在指定修饰符。

  1. let regex3 = new RegExp(/abc/ig, 'i');
  2. console.log(regex3.flags); // i

以上示例中,原有正则对象的修饰符是ig,它会被第二个参数i覆盖。

字符串扩展

  • Unicode表示法
  1. {
  2. console.log('a',`\u0061`); //a a
  3. //乱码,因为\u20bb7转换成二进制以大于0xFFFF,会当做两个字符处理
  4. console.log('s',`\u20BB7`); //s ₻7
  5. //ES6中处理大于0xFFFF这种情况,用大括号{}把这种Unicode编码包括起来
  6. console.log('s',`\u{20BB7}`); //s 𠮷
  7. }
  1. {
  2. let s='𠮷';
  3. //取长度,四个字节为两个字符
  4. console.log('length',s.length); //2
  5. //ES5中charAt()取字符,charCodeAt()取码值
  6. console.log('0',s.charAt(0)); //0 �
  7. console.log('1',s.charAt(1)); //1 �
  8. console.log('at0',s.charCodeAt(0)); //at0 55362
  9. console.log('at1',s.charCodeAt(1)); //at1 57271
  10. //ES6中codePointAt()取码值,toString(16)转换成16进制
  11. let s1='𠮷a';
  12. console.log('length',s1.length);
  13. console.log('code0',s1.codePointAt(0)); //code0 134071
  14. console.log('code0',s1.codePointAt(0).toString(16)); //code0 20bb7
  15. console.log('code1',s1.codePointAt(1)); //code1 57271
  16. console.log('code2',s1.codePointAt(2)); //code2 97
  17. }
  1. {
  2. //ES5中fromCharCode()处理大于两个字节,会乱码
  3. console.log(String.fromCharCode("0x20bb7")); //ஷ
  4. //ES6中fromCodePoint()处理大于两个字节,正常显示
  5. console.log(String.fromCodePoint("0x20bb7")); //𠮷
  6. }
  • 遍历接口

    1. //字符串遍历器接口
    2. let str='\u{20bb7}abc';
    3. //ES5处理会将{20bb7}按照两个字节处理,造成前一个字符乱码
    4. for(let i=0;i<str.length;i++){
    5. console.log('es5',str[i]);
    6. }
    7. //输出结果:� � a b c
    8. //ES6使用for of遍历处理,可以自动处理大于0xFFFF这种情况
    9. for(let code of str){
    10. console.log('es6',code);
    11. }
    12. //输出结果:𠮷 a b c
  • 模板字符串

  1. {
  2. let name = "张三";
  3. let info = "我来自China";
  4. let str = `I am ${name} , ${info}`;
  5. console.log(str);
  6. }
  7. {
  8. //row对所有的斜杠进行了转义,原样输出
  9. console.log(String.raw`Hi\n${1+2}`);//Hi\n3
  10. console.log(`Hi\n${1+2}`);
  11. }
  • 标签模板

标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的是函数,紧跟在后面的模板字符串就是它的参数。

两个作用: 第一在过滤 html 字符串的时候防止 xss 攻击用这个处理,第二可以用于多语言转换

  1. {
  2. let user = {
  3. name:'zhangsan',
  4. info:'hello world'
  5. }
  6. console.log(abc`I am ${user.name},${user.info}`);
  7. function abc(s,v1,v2){
  8. console.log(s,v1,v2);
  9. return s+v1+v2;
  10. }
  11. }
  • 新增方法(10种)

padStart()、padEnd() 这两个方法是 ES7 的草案中提案的,在 ES6 中使用,需要安装库 npm install babel-polyfill --save-dev 打补丁,处理兼容性,在项目中引入 babel-polyfill

  1. import 'babel-polyfill'
  1. {
  2. let str="string";
  3. //includes()判断是否包含某个字符
  4. console.log('includes',str.includes("c"));
  5. //startsWith()判断是否以某个字符为起始
  6. console.log('start',str.startsWith('str'));
  7. //endsWith()判断是否以某个字符为结束
  8. console.log('end',str.endsWith('ng'));
  9. }
  1. {
  2. let str="abc";
  3. //repeat()使字符串重复多少次
  4. console.log(str.repeat(3));
  5. }
  1. {
  2. //第一个参数指定要显示的长度,第二个参数表示如果长度不够要添加的字符
  3. console.log('1'.padStart(2,'0')); //01
  4. console.log('1'.padEnd(2,'0')); //10
  5. }

数值扩展

  • Number.isInteger()

判断是否为整数

  1. console.log('25',Number.isInteger(25)); //true
  2. console.log('25.0',Number.isInteger(25.0)); //true
  3. console.log('25.1',Number.isInteger(25.1)); //false
  4. console.log('25.1',Number.isInteger('25')); //false
  • Number.isFinite()

函数用于检查其参数是否是无穷大

  1. console.log('15',Number.isFinite(15)); //true
  2. console.log('NaN',Number.isFinite(NaN)); //false
  3. console.log('1/0',Number.isFinite('true'/0)); //false
  4. console.log('NaN',Number.isNaN(NaN)); //true
  5. console.log('0',Number.isNaN(0)); //false
  • Number.isNaN()判断是否为一个数
    1. console.log('NaN',Number.isNaN(NaN)); //true
    2. console.log('0',Number.isNaN(0)); //false
  • Number.MAX_SAFE_INTEGER

    一个数的最大上限

  • Number.MIN_SAFE_INTEGER

    一个数的最小下限

  • Number.isSafeInteger()

    判断给的这个数是否在有效范围内

注意: ES6中如果一个数不在-2的53方和2的53次方之间就会不准确

  1. {
  2. console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);
  3. console.log('10',Number.isSafeInteger(10));//10 true
  4. console.log('a',Number.isSafeInteger('a'));//a false
  5. }
  • Math.trunc()

    取整

    1. {
    2. console.log(4.1,Math.trunc(4.1)); // 4
    3. console.log(4.9,Math.trunc(4.9)); // 4
    4. }
  • Math.sign()

    返回-1,0,1 小于0返回-1,等于0返回0,大于0返回1,注意参数为数值

    1. console.log('-5',Math.sign(-5)); //-1
    2. console.log('0',Math.sign(0)); //0
    3. console.log('5',Math.sign(5)); //1
  • Math.cbrt()

    返回一个数的立方根

    1. {
    2. console.log('-1',Math.cbrt(-1)); //-1
    3. console.log('8',Math.cbrt(8)); //2
    4. }

数组扩展

  • Array.of()

把一组数组变量转换成数组类型

  1. {
  2. let arr = Array.of(3,4,7,9,11);
  3. console.log('arr=',arr); //arr= [3, 4, 7, 9, 11]
  4. //返回空数组
  5. let empty=Array.of();
  6. console.log('empty',empty); //empty []
  7. }
  • Array.from()

    1. {
    2. //第一种用法,传入一个参数
    3. <div id="doc3" class="syy">
    4. <p>p1</p>
    5. <p>p2</p>
    6. <p>p3</p>
    7. </div>
    8. //获取所有的p标签
    9. let p=document.querySelectorAll('p');
    10. let pArr=Array.from(p);
    11. pArr.forEach(function(item){
    12. //textContent是ES5的一个原生方法,获取文本
    13. console.log(item.textContent);
    14. });
    15. //输出 p1 p2 p3
    16. //第二种用法传入两个参数,第二个参数类似于map映射
    17. console.log(Array.from([1,3,5],function(item){return item*2})); //[2, 6, 10]
    18. }
  • fill()

填充,只写一个参数全部替换,三个参数情况下:第一个参数是替换内容,第二个参数是起始位置,第三个参数是结束位置

  1. {
  2. console.log('fill-7',[1,'a',undefined].fill(7)); //[7, 7, 7]
  3. console.log('fill,pos',['a','b','c'].fill(7,1,3));//["a", 7, 7]
  4. }
  • keys()

    获取索引

  • values()

    获取值,是ES7中的一个提案,存在浏览器兼容性需要加载 import 'babel-polyfill';

  • entries()

    既获取索引又获取值

    1. {
    2. for(let index of ['1','c','ks'].keys()){
    3. console.log('keys',index); // 0 1 2
    4. }
    5. for(let value of ['1','c','ks'].values()){
    6. console.log('values',value); //1 c ks
    7. }
    8. for(let [index,value] of ['1','c','ks'].entries()){
    9. console.log('values',index,value); //0 1 1 c 2 ks
    10. }
    11. }
  • copyWithin(target,start,end)

    • target(必须):从该位置开始替换数据
    • start(可选):从该位置开始读取数据,默认为0
    • end(可选):到该位置前停止读取数据,默认等于数组长度
  1. {
  2. console.log([1,2,3,4,5].copyWithin(0,3,4)); //[4, 2, 3, 4, 5]
  3. }
  • find()

    查找符合的元素,直返会一个

  • findIndex()

    查找符合元素的下标

  1. {
  2. console.log([1,2,3,4,5,6].find(function(item){return item>3})); //4
  3. console.log([1,2,3,4,5,6].findIndex(function(item){return item>3})); //3
  4. }
  • 展开运算符…

    数组拼接使用展开运算符可以取代concat的位置

  1. const a = ['a', 'b'];
  2. const b = ['c', 'd']
  3. const c = [...a, ...b];
  4. console.log(c); //["a", "b", "c", "d"]
  5. //使用concat
  6. const d = a.concat(b)
  7. console.log(d); //["a", "b", "c", "d"]

函数扩展

  • 参数默认值

注意: 默认值后面不能跟没有默认值得变量,如(x, y = ‘world’,c)c没有默认值错误

  1. {
  2. function test(x, y = 'world'){
  3. console.log('默认值',x,y);
  4. }
  5. test('hello'); //默认值 hello world
  6. test('hello','China'); //默认值 hello China
  7. }
  • 作用域问题

    1. {
    2. let x='test';
    3. function test2(x,y=x){
    4. console.log('作用域',x,y);
    5. }
    6. //参数中第一个x没有值
    7. test2(); //作用域 undefined undefined
    8. test2('kill'); //作用域 kill kill
    9. //x为上面let定义的x
    10. function test3(z,y=x){
    11. console.log('作用域',z,y);
    12. }
    13. test3('kill'); //作用域 kill test
    14. }
  • rest参数

    rest参数就是在你不确定有多少个参数的时候,把你输入的一系列参数转换成了数组

    1. {
    2. function test3(...arg){
    3. for(let v of arg){
    4. console.log(v);
    5. }
    6. }
    7. test3(1,2,3,4,'a'); // 1 3 4 5 a
    8. }
  • 扩展运算符

    ES6的扩展运算符则可以看作是rest参数的逆运算。可以将数组转化为参数列表

    1. {
    2. // 把一个数组拆分成离散的值
    3. console.log(...[1,2,4]); //1 2 4
    4. console.log('a',...[1,2,4]); //a 1 2 4
    5. }
  • 箭头函数

    1. {
    2. let arrow = v => v*2;
    3. let arrow2 = () => 5;
    4. console.log('arrow',arrow(3)); //6
    5. console.log(arrow2()); //5
    6. }
  • this绑定

  • 尾调用

    尾调用存在于函数式编程概念里,函数的最后是不是是一个函数,可以用来提升性能,如果在性能优化过程中,是不断的嵌套其他函数,或者说这个函数依赖于另一个函数的操作,建议用尾调用的形式。

  1. {
  2. function tail(x){
  3. console.log('tail',x);
  4. }
  5. function fx(x){
  6. return tail(x)
  7. }
  8. fx(123) //tail 123
  9. }

对象扩展

  • 简洁表示法
  1. {
  2. let o=1;
  3. let k=2;
  4. //es5属性定义
  5. let es5={
  6. o:o,
  7. k:k
  8. };
  9. //es6属性定义
  10. let es6={
  11. o,
  12. k
  13. };
  14. console.log(es5,es6);
  15. //es5定义方法
  16. let es5_method={
  17. hello:function(){
  18. console.log('hello');
  19. }
  20. };
  21. //es6定义方法,更简洁
  22. let es6_method={
  23. hello(){
  24. console.log('hello');
  25. }
  26. };
  27. console.log(es5_method.hello(),es6_method.hello());
  28. }
  • 属性表达式
  1. {
  2. // 属性表达式
  3. let a='b';
  4. //es5中key是固定的
  5. let es5_obj={
  6. a:'c',
  7. b:'c'
  8. };
  9. //es6中可以使用变量,这块相当于b
  10. let es6_obj={
  11. [a]:'c'
  12. }
  13. console.log(es5_obj,es6_obj);
  14. //输出 Object {a: "c", b: "c"} Object {b: "c"}
  15. }
  • 新增API

  • Object.is()

在功能上与===一样

  1. {
  2. console.log('字符串',Object.is('abc','abc'),'abc'==='abc'); //字符串 true true
  3. // 数组是引用类型,虽然以下是两个空数组,在值上都是空,但这两个数组引用的是不同的地址,因此在严格意义上来讲,他两个不是完全相等的
  4. console.log('数组',Object.is([],[]),[]===[]); //数组 false false
  5. }
  • Object.assign()

    拷贝函数

    1. console.log('拷贝',Object.assign({a:'a'},{b:'b'}));
    2. //拷贝 Object {a: "a", b: "b"}
  • Object.entries()

    遍历

    1. let test={k:123,o:456};
    2. for(let [key,value] of Object.entries(test)){
    3. console.log([key,value]);
    4. }
  • Object.keys()

    对数组排序

    1. var anObj = { 100: 'a', 2: 'b', 7: 'c' };
    2. console.log(Object.keys(anObj).sort( (x,y) => x > y));
  • 对象扩展拷贝

    node v8.5.0版本支持

    1. const a = {"name": "zhangsan"}
    2. const b = {"age": 8, "email": "XXX@qq.com"}
    3. console.log({...a, ...b, "type": "儿童"});
    4. // {name: "zhangsan", age: 18, email: "XXX@qq.com", type: "成人"}