ES6 语法

Posted 白纱茗-度C

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 语法相关的知识,希望对你有一定的参考价值。

  1. let
    • let 定义变量没有变量的提升(没有预解释)
    • let 定义的变量不能重复定义(无论函数还是let定义的变量都不可以重复定义)
    • 虽然不进行预解释,但是代码执行前,也是将定义的变量提前过滤一遍,一旦发现不合法的就直接报错了,代码也不会执行了。
  2. { } 
    • 是一个私有作用域 ,块级作用域 
    • // 自执行函数 { let a = 100; console.log(a); }
    • 注意:eval将字符串转为对象的时候,一定要加一个()
 
let test = "{ name: ‘Tom‘, age: ‘28‘ }";
let obj = eval(‘(‘+ test +‘)‘);
console.log(‘obj:‘,obj);    
    
    3. const
  • 定义的是静态变量(常量),不能修改值,必须要赋值(不赋值会报错)
  • const不能重复声明(不管变量a是let动态变量,还是const静态变量,都不可以重复定义)----前提:同一作用域下
 
    4. 数组赋值        
  • 解构赋值
let [a,b,c] = [1,2,3];
console.log(a,b,c); //1,2,3
 
let ary = ["a", "b"];
let [a,b,c] = ary;
console.log(a,b,c);  //a,b,undefined
 
let ary = ["a", "b", "c", "d"];
let [a,b,c] = ary;
console.log(a,b,c);  //a,b,c
  • 嵌套赋值
let [x,y,[s],[[f]]] = [1,2,[3],[[4]]];  // s、f均为变量,非数组
console.log(x,y,s,f);
  • 省略赋值
let array= [1,2,3,4,5];
let a = array[0];
let b = array[array.length - 1];
 
//x是array的第一项,y是array的第五项
let [x,,,,y]=array;
console.log(x,y);
  • 不定参数赋值
let [a,...b] = [1,2,3,4,5];
console.log(a,b); // 1, [2,3,4,5]
 
let [,,x,,...y] = [1,2,3,4,5,6,7,8,9,0];
console.log(x,y);
  • 默认值
// 1、变量名==属性名
let {n1, n2} = obj;
console.log(n1,n2);
// 2、变量名不等于属性名
let {n1: x1, n2: x2} = {n1: ‘n1‘, n2: ‘n2‘};
let {n, m:m1} = {n: ‘nn‘, m: ‘mm‘};
console.log(n,m1); //
 
 
let [f0,f1]= [1];
console.log(f0,f1);
 
let [f2,f3=2] = [1];
console.log(f2,f3);
//判断一个位置是否有值,严格===判断,如果数组中成员不严格等于undefined,默认值不会生效。
let [f=1] = [null];
console.log(f);
 
 
function fn(){
    console.log("哈哈哈");
}
let [x=fn(),y=0] = [1];
console.log(x,y);
//只要变量(比如x)所占在数组中的位置的值不是undefined,fn()根本不会触发执行
  1. 对象赋值
    • 解构赋值
let {x,y="Y"}={x:"X",y:"YY"};
    let {m:[m1],n}={m:[1],n:1};
 
  //赋的值不是一个对象,是个其他数据类型的值,会默认将其他数据类型转为对象,再进行解构赋值
    let {x,y,__proto__}=1; //{__proto__:Number}
  console.log(x,y); //undefined,undefined
    console.log(__proto__);
    console.log(Object(1));    //{__proto__:Number}
 
 
    let {b,constructor}=Boolean.prototype;
 
    console.log(Object(Boolean.prototype));
    console.log(constructor);
 
    //没有默认值的形参的长度
    let {length,name} = function (a,b=1) {    };
    console.log(Object(function (a, b) {    }));
    console.log(length,name);
 
    //null和undefined 不能转为对象 会报错
    //let {nn}=null;
    let {mm}=undefined;
    console.log(nn);
    console.log(mm);
  • 对象数组的嵌套
let obj = {a1:[1,2,3], a2:"123"};
//x=obj.a1[0]、y=obj.a1[1]
let {a2, a1:[x,y]} = obj;
console.log(a2, x, y);
 
let obj1 = {s:{n:‘1‘}, n:[1,‘2‘,3,‘4‘], m:[[1]]};
let {m:[x1], s:{n}, n:[,...m2]} = obj1;
console.log(x1,n,m2); //[1], ‘1‘, [‘2‘,3,‘4‘]
  • 默认值
let obj = {y: 2};
console.log(obj.x); //undefined
let {x=1,y} = {y: 2};
console.log(x,y); 
 
let {m:n} = {}; //m: undefined
console.log(n); //n: undefined
 
let {m:n=4} = {}; //m: undefined
console.log(n); //n: 4
 
let {a:cc=22} = {a: 12};
console.log(cc); //12
//默认值生效的条件是对象的属性必须是undefined 
let {v=3} = {v: undefined};
console.log(v); // v:3 
let {v=3}={v:null};
console.log(v); //null
 
let {f:{b}} = {b: ‘bb‘};
//f: undefined
//{b}=undefined
console.log(b);  //Cannot destructure property `b` of ‘undefined‘ or ‘null‘
//如果解构模式中嵌套的是对象,而且子对象所在的父属性不存在,就会报错
 
  • 其他问题
  1. 赋的值不是一个对象,是个其他数据类型的值,会默认将其他数据类型转为对象;
  2. 为了避免错误,不要将{}写在行首,javascript引擎会将{a}理解为一个代码块;
  3. null和undefined 不能转为对象 会报错
  • 比如:eval("{s: ‘ss‘,d: ‘d‘}");
  • ({a}={a: ‘a‘}); console.log(a); //a
 
6. 字符串
  • 解构赋值
//此时是将字符串转为类似数组的一个对象
let [x,y,z] = ‘123‘;
console.log(x,y,z);
 
let {length} = ‘12345‘;
console.log(length);            
  • 方法
    • includes();  //判断字符串中有没有指定字符,有的话返回true,没有返回false、第二个参数~~开始查找的索引,默认是0;
    • startsWidth(); //是不是以某个字符作为开头,第二个参数:开始查找的索引,默认是0;true/false
    • endsWidth(); //是不是以某个字符作为结尾,第二个参数:开始查找的索引,默认是0;true/false
let str = ‘asdfghjkl‘;
console.log(str.includes(‘a‘,2));
 
console.log(str.startsWith(‘a‘,2));
console.log(str.endsWith(‘l‘));
  • repeat(n); //将 字符串重复n次返回,原字符串不变 
 
console.log(str.repeat(2),str);
 
//小数,向下取整
console.log(str.repeat(2.6));
 
//负数、Infinity  报错
console.log(str.repeat(-2));
console.log(str.repeat(Infinity));
 
//0~-1,  先向下取整运算结果为0
console.log(str.repeat(-0.3)); // ‘‘
 
//NaN  -->  0
console.log(str.repeat(NaN)); // ‘‘
 
//字符串, 将字符串转为数字
console.log(str.repeat(‘2‘)); // ‘asdfghjklasdfghjkl‘
console.log(str.repeat(‘sdfsdf‘)); // ‘‘
 
 
  • 模板字符串(字符串)
let str = ‘I love U‘;
document.body.innerhtml = ‘<h1>‘+ str +‘</h1>‘;
 
//模板字符串
let str1 = `<h1>${str}</h1>`; //拼接字符串
document.body.innerHTML += str1;
 
//es6 保留换行和空格
console.log(‘hahahahah\nhahahah‘); //平时\n 换行 console 
let s1 = `hhhha
the weather is
fine.
`;
console.log(s1); //es6保留换行 console
 
//`特殊符号需转义(\`)
console.log(`sss\`1234`);
 
//{可以实现运算}
let x=1;
let y=2;
console.log(`${x}+${y}=${x+y}`);
 
//调用函数
function fn(x){
    return x;
}
let s2 = ‘sss‘;
console.log(`函数fn输出的结果是${fn(s2)}`);
 
let s3 = ‘return‘ + ‘`hello ${wd}`‘;
let fun = new Function(‘wd‘,s3);
fun(‘ZFPX‘);
 
7. 数组的扩展
  • Array.from(), Array.of()
// Array() ----即是一个类,也是一个方法,将传进来的值变成数组返回;【注意】只传一个参数n,代表返回数组的长度(4个空位)(eg: Array(1,2,3,4)、Array(4))
 
//1、Array.of ----跟Array()一样,只有一点区别:就是传一个参数时候返回就是当前参数组成的数组(eg: Array.of(1,2,3,4)、Array.of(4))
 
//2、Array.from() ----参数是:数组或者类数组;返回值是一个新的数组。将类数组对象( 所谓类数组对象,最基本的要求就是具有length属性的对象)变成数组
  • 数组实例的copyWithin()
copyWithin(target,start,end);
   //target: 必填,从该位置开始替换数据
   //start: 选填,默认值0,从该位置开始读取数据
   //end: 选填,默认值是数组的长度,到该位置前停止读取数据 
  • 数组实例的find() 和 findIndex()
//1、find ----先遍历数组,一项一项的执行,一旦函数返回值是true,停止查找,返回当前项,一直到最后一项还没有返回true,最终结果就是undefined。
    let arr = [1,2,3,4,5,6];
      arr.find(function (item, index, input){ 
           //item:当前项, index:索引, input: 原数组
           return item==4;
     });
 
//2、findIndex ----返回值是当前项的索引,一直到最后都没有返回true的最终结果就是undefined
  • 数组实例的fill()
fill(value,start,end) ----填充数组的
   //value: 必填的,填充的值
   //start: 开始填充的位置,默认值0,可选的
   //end: 停止填空的位置,可选的,不包括
 
eg: //得到有7个1的数组
    Array(7).fill(1);
  • 数组实例的entries() 和 keys()
//1、keys() ----数组索引值
eg: let arr = [1,2,3,4,5];
    for(var key in arr){
        console.log("索引"+key);
    };
 
    for(let item of arr){
        console.log("当前项"+item);
    }
 
    //keys()  遍历索引
    for(let key of arr.keys()){
        console.log(key);
    }
 
//2、entries() ----索引+对应项的值
    for(let [index,item] of arr.entries()){
        console.log(index,item);
    }
  • 数组实例的includes()
includes() ----判断数组中有没有某一项,返回值是true/false
  • 数组的空位
//1、ES5中方法对空位处理都不太一致,大部分都是跳过空位
    [1,,,2,,].forEach(function(item){
        console.log(item);
    });
 
//2、ES6不跳过空位,会将空位处理为undefined
    [1,,,2,,].map(function(item){
        return item;
    });
 
  1. 函数的扩展时
    • 函数参数问题
      • 一般把函数形参变量的默认值放后面
        • function fn(x,y,z=1){ }; fn(1,2);
      • 参数集合
        • function fn5(){ console.log(arguments.length); }; fn5(1,2,3,4,5); // arguments.length~~实参的长度
        • function fn6(x,y,z){}; console.log(fn6.length); //1、形参没有默认值,fn6.length:形参的长度;2、形参有默认值,fn6.length是默认值参数的位置
    • 参数作用域问题
      • 形参所在的小括号是一个单独的作用域,遇到了变量,想看自己作用域下有没有,没有再往上一级找
    • 扩展运算符  ...
      • ...  可以将数组变成非数组,也可以将非数组变成数组
        • let ary=[123];console.log(...ary);
      • ... 可以将字符串变成数组
        • let str=‘12345‘;console.log([...str]);
      • ... 可以将类数组变成数组
        • function fn(){ return  [...arguments].sort() }; fn(3,2,5,4,1,6);
      • ... 应用场景
        • 求最大值的方法 let ary1 = [1,3,2,31,123,234];
          1.  //eval   :eval("Math.max("+ ary1 +")");
          2. //apply   : Math.max.apply(null, ary1);
          3. //...    :Math.max(...ary1);
    • 函数的name
      • let fn = function(){}; console.log(fn.name); // fn
      • 匿名函数name:  console.log((function(){}).name); // ‘‘
      • bind ----> bound fn
        • let obj = {};var fn1=fn.bind(obj);fn1(); console.log(fn1.name); //bound fn
      • new Function ----> anonymous
        • let f= new Function(‘n‘, ‘return n‘);console.log(f.name); //anonymous
    • 箭头函数
let fn = function(){
    let a=1;
    return a;
}
 
let fn = (x) => {
    let a =1;
    return a;
}
 
// x=> x;   如果函数体只有一行代码而且是return,可以简写成这样
 
function fn(x){
    return x;
}
  • 箭头函数中this问题
    • 箭头函数没有this指向,它里面的this是谁----看它上一级作用域中的this(保证上一级函数不是箭头函数 )
let obj = {
    fn: function(){
        console.log(this);
        let f=()=>{
            console.log(this);
        }
           f();
    },
    fn1: ()=>{
        console.log(this);
    }
};
obj.fn();  //this==obj
obj.fn1(); //this==window
 
document.querySelector(‘#box‘).onclick=()=>{
    console.log(this); //window
};
 
 
  1. 对象的扩展
    • 属性的简洁表示
let a = ‘aa‘, b=‘bb‘;
let obj = {
    [a]: ‘AAA‘,  //属性,通过变量传值
    [a+b]: ‘AAA+BBB‘,
    fn(){
 
    },
 
    /*
    fn: function(){
 
    }
    */
 
};
console.log(obj.a);
console.log(obj[‘a‘]);
console.log(obj);
  • Object类上的方法
    • Object.is();
      • console.log(Object.is(NaN, NaN));
//数组去重
let arr = [1,2,NaN,NaN,1,3];
let newArr = [];
arr.forEach((item)=>{
   var flag = true;
    for(var i=0;i<newArr.length;i++){
       if(Object.is(item, newArr[i])){
            flag = false;
       }
   }
    if(flag){
        newArr.push(item);
    }
});
 
console.log(newArr);
  • Object.assign(obj1, obj2);
    • 将obj2合并到obj1上,返回obj1
  • Object.getOwnPropertyDescriptor();  //获取对象的属性描述
console.log(Object.getOwnPropertyDescriptor(str, ‘length‘));
 
console.log(Object.getOwnPropertyDescriptor([1,2,3], ‘length‘));
  • 属性的变量
    • for   in
    • Object.keys()
      • 返回值是一个数组,包括对象自身的(私有属性)所有的可枚举的属性;
    • Obeject.getOwnPropertyNames()
      • 返回值是一个数组,包括对象自身的(私有属性)所有的不可枚举的属性;
 
 
  1. Set 和 Map 数据结构
    • Set
      • 1、使用构造函数方式创建Set的实例;参数是个数组,返回值是一个Set实例,去重后的类数组;
let set1 = new Set([1,2,3,NaN,NaN,1,2,3,4,5]);
console.log(set1);
 
//将Set实例变成数组
console.log([...set1]); //1、... 将类数组转化为数组
console.log(Array.from(set1)); //2. Array.from()  将类数组转为数组
 
 
/* 利用set实现数组去重 */
function fn(arr){
    return [...new Set(arr)];
}
console.log(fn([1,1,1,1,3,3,5,76,4,65]));
  •   2、Set原型上的方法(let set = new Set([1,2,3,1,2,3]))
    • size 长度
    1. add()  ----增加一项,之前没有才可以加上,加在后面。返回值是当前实例,实现链式写法
      • console.log(set.add(5).add(4));
    2. has() ----判断有没有某一项,返回值是true、false
      • console.log(set.has(1));
    3. delete() ----删除,返回值是true、false
      • console.log(set.delete(6));
      • console.log(set);
    4. clear() ----清空,没有返回值,undefined
      • console.log(set.clear());
      • console.log(set);
let arr1 = [1,2,3,4,5,6];
let arr2 = [2,4,6,8,10];
 
//数组并集
function bj(arr1,arr2){
    return [...new Set([...arr1,...arr2])];
}
bj(arr1,arr2);
 
//数组交集
function jj(arr1,arr2){
    return arr1.filter((item)=>{
        return arr2.includes(item);
    });
}
jj(arr1,arr2);
 
//数组差集
function cj(arr1,arr2){
    return bj(arr1,arr2).filter((item)=>{
        return !jj(arr1,arr2).includes(item);
    });
}
cj(arr1,arr2);
 
 
    var set1=new Set(["z","h","u","f","e","n","g"]);
    console.log(set1);
    //遍历set数据的实例只能遍历value值
    set1.forEach((item,index)=>{
        //item当前项
        console.log(item, index);
    });
 
    for(var key of set1.keys()){
        console.log(key);
    }
    for(var val of set1.values()){
        console.log(val);
    }
    for(var en of set1.entries()){
        console.log(en);
    }
 
 
  • Map
    • 1.使用构造函数方式创建一个实例
    • 2.参数是个数组,数组的每一项都是一个数组,这个数组有两项,第一项作为键key,第二项作为值value
    • 3.这里的key键可以是任意数据类型的
    var map1=new Map([[1,"a"],["a","A"],[{name:"珠峰"},"珠峰"],[/\d+/,"正则"]]);
    console.log(map1);
 
    //方法
    //get(key)
    console.log(map1.get("a"));
 
    //set(key,value);
    map1.set(2,"JS");
    console.log(map1);
    //delete,has,clear
 
    let ary=[1,2,3,4,5,6];
    //将数组变成Map
    //1,[1]
    //2,[1,2]
    //3,[1,2,3]
    //....
    var map=new Map();
    ary.forEach((item,index)=>{
        map.set(index+1,ary.slice(0,index+1))
    });
    console.log(map);
 
    //forEach(),keys(),values(),entries();
 
    map.forEach((val,key,map)=>{
        //val:值,
        //key:键
        //map:原Map实例
    })
    for(var key of map.keys()){
        //key:键
    }
    for(var val of map.values()){
        //val:值,
    }
    for (var [key,val] of map.entries()){
        //val:值,
        //key:键
    }


 






 
 
 

以上是关于ES6 语法的主要内容,如果未能解决你的问题,请参考以下文章

使用webpack+babel构建ES6语法运行环境

ES6 Class 基础语法

ES6最新语法

ES6常用语法

总结常见的ES6新语法特性

Es6新增语法梳理