ES6后知后觉

引言:

ES全称ECMAScript,ECMAScript是ECMA制定的标准化脚本语言。目前JavaScript使用的ECMAScript版本为ECMA-417。关于ECMA的最新资讯可以浏览 ECMA news。

 

为什么学习ES6+ ?

       ES5发布近5年后才被标准化,ES6+新特性让开发更高效

 

前置知识:

  1. 熟悉ES5
  2. 了解ES6+
     

隐藏着黑暗力量的钥匙啊,在我面前显示你真正的力量!迷人又刷漆的大帅比 or 美丽又善良的xiao镁铝 ?  封印解除!!!durang~~

 

  1. 新的声明方式

    ES6之前,JS是没有块级作用域的,const与let填补了这方便的空白,const与let都是块级作用域。
    1. var:variable的简写,可理解成变量的意思。
    2. let:英文中表示“让”,也是一种声明方式。
    3. const:英文表示常量,ES6中用来声明常量,常量你可以简单理解为不变的量,类似Java中的枚举。
    var a = 'awesome';
    console.log(a);  // awesome

     

    var a = 'awesome'
    {
      var a = ‘cool’;
    }
    console.log(a);  // 不会报错,且打印出cool

    对比以上两段代码,得出以下结论:var在ES6存在变量提升特性。

     

     

    var a = 'awesome';
    {
       let a = 'cool';
    }
    console.log(a); // awesome

     

    {
       let a = 'awesome';
    }
    console.log(a); // Uncaught ReferenceError: a is not defined

    let声明块级作用域

     

    for(var i = 0; i < 10; i++){
    	console.log('循环体中:' + i);
    }
    console.log('循环体外:' + i);

     

    for(let i = 0; i < 10; i++){
    	console.log('循环体中:' + i);
    }
    console.log('循环体外:' + i);

     

    var返回结果:

    ES6后知后觉_第1张图片

    let返回结果

  2. ES6后知后觉_第2张图片

结论:let在防止程序数据污染。for循环let声明,减少var声明污染全局空间

 

const a = 'awesome';
var a = 'cool';
console.log(a);  // Uncaught SyntaxError: Identifier 'a' has already been declared

有些变量是希望声明后在业务层就不再发生变化,这时用const声明

 

 

  1. 变量的解构赋值

    数组的解构赋值: 

    从前:

    let a=0;
    let b=1;
    let c=2;

    现在:

    let [a, b, c]=[1,2,3];
    let [a,[b, c],d]=[1,[2,3],4];


    解构默认值:

    // --------------- foo = true -------------------------------------------------
    let [foo = true] =[];
    console.log(foo); // 控制台打印出true
    
    
    // ---------------- b="awesome" ------------------------------------------------
    let [a, b="awesome"]=['大数据']
    console.log(a+b); // 控制台显示“大数据awesome”
    
    
    // ----------------- undefined相当于没有定义了但是没有值,所以b取默认值。 --------------------------
    let [a, b="awesome"]=['大数据',undefined];
    console.log(a+b); // 控制台显示“大数据awesome”
    
    
    // ----------------- null相当于有值,但值为null。所以b并没有取默认值,而是解构成了null。 -------------------
    let [a, b="awesome"]=['大数据',null];
    console.log(a+b); // 控制台显示“大数据null”
    
    


    对象解构赋值

    let {foo, bar} = {foo:'awesome',bar:'大数据'};
    console.log(foo+bar); // 控制台打印出“awesome大数据”
    
    
    let json = {
        a:'jack',
        b:'马云'
    }
    function fun({a, b='syk'}){
        console.log(a, b);
    }
    fun(json);  // 输出jack 马云  ≈ 执行了 fun({a, b='syk'} = {a:'jack', b:'马云'}})
    
    

    PS:对象的解构与数组解构不同:

             a. 数组的元素是按次序排列,变量的取值由位置决定;

             b. 对象的属性没有次序,变量须与属性同名,才可取到正确的值。
     

    圆括号的使用

    let foo;
    {foo} ={foo:'awesome'};
    console.log(foo);
    解构之前定义变量,解构会出现问题。

    解决方案 —— 外部加圆括号

    let foo;
    ({foo} ={foo:'awesome'});
    console.log(foo); //控制台输出awesome


     

    字符串解构

     

    const [a, b, c, d, e, f]="awesome";
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(d);
    console.log(e);
    console.log(f);
     
  2. 扩展运算符和rest运算符

    对象扩展运算符(…)

    // 编写一个方法时,我们允许它传入的参数是不确定的:
    function myFunc(...arg){
        console.log(arg[0]);
        console.log(arg[1]);
        console.log(arg[2]);
        console.log(arg[3]);
    }
    myFunc(1,2,3);
    // 数组构造或字符串:
    [...iterableObj, '4', ...'hello', 6];
    
    
    // 构造对象时,进行克隆或者属性拷贝(ECMAScript 2018规范新增特性):
    let objClone = { ...obj };
    
    
    
    

    rest运算符

    // 编写一个方法时,我们允许它传入的参数是不确定的:
    function myFunc(first, ...arg){
        console.log(arg.length);
    }
     
    myFunc(0,1,2,3,4,5,6,7);  // 控制台输出7,说明arg中有7个元素

     

    // 编写一个方法时,我们允许它传入的参数是不确定的:
    function myFunc(first, ...arg){
        for(let val of arg){
            console.log(val);
        }
    }
     
    myFunc(0,1,2,3,4,5,6,7);  // 控制台输出1 2 3 4 5 6 7

     

  3. 字符串模版

    // -----------------------  拼接字符串  -----------------------------
    
    
    const [first, last0 = ['curry','james']
    // 不使用模板字符串
    let name = 'Your name is ' + first + ' ' + last + '.'
    
    
    // 使用模板字符串
    let name = `Your name is ${first} ${last}.`   // 外层用反引号
    
    
    
    // -----------------------  字符串查找  -----------------------------
    // ES5写法
    const jj = '林俊杰';
    const news = '2019年8月20日,林俊杰来到上海趣头条大数据部,与大数据部同学们一起研究ES6...'
    console.log(news.indexOf(jj))  // 返回11,需要在条件中判断11是否大于-1,来查找字符串
    
    
    ES6写法:
    console.log(news.includes(jj))  // 返回true
    
    
    // -----------------------  字符串复制  -----------------------------
    console.log('stephen'.repeat(3))  // 返回stephenstephenstephen 实际应用场景不多
    
    


     

  4. 数字

    // -----------------------  Number.isFinite( ):数字验证,只要是数字,不论是浮点型还是整形都返回true,其返回false。  -----------------------------
    let a = 11/4;
    console.log(Number.isFinite(a)); // true
    console.log(Number.isFinite('jack')); // false
    console.log(Number.isFinite(NaN)); // false
    console.log(Number.isFinite(undefined)); // false
    
    
    // -----------------------  Number.isNaN( ):NaN是特殊的非数字,可以使用Number.isNaN()来进行验证  -----------------------------
    console.log(Number.isNaN(NaN));  // true
    
    



     

  5. 数组

    // -----------------------  Array.from():Json对象转数组  -----------------------------
    let  json = {
        '0': 'Sephirex',
        '1': '王思聪',
        '2': '国名老公',
        length:3      // 必要条件,对象中前几个属性须严格定义为0、1、2 字符串
    }
    let arr=Array.from(json);
    console.log(arr)  // ["Sephirex", "王思聪", "国名老公"]
    
    
    
    
    
    
    // -----------------------  Array.of() :文本或者变量转换成数组 -----------------------------
    // --- 数字
    let arr =Array.of(3,4,5,6);
    console.log(arr);
    
    
    // --- 字符
    let arr =Array.of('王思聪','Sephirex','国名老公');
    console.log(arr);
    
    
    
    // -----------------------  Array.find() :传入匿名函数,查找指定值 -----------------------------
    
    let arr=[1,2,3,4,5,6,7,8,9];
    console.log(arr.find(function(value, index, arr){
        return value > 5;
    }))
    // 返回6,如果找不到会显示undefined
    
    
    
    
    // -----------------------  Array.fill() :填充数组 ----------------------------------------
    let arr=[0,1,2,3,4,5,6,7,8,9];
    arr.fill('james',2,5);  // 接收三个参数,填充的变量,开始填充的位置,填充到的位置。
    console.log(arr); // 输出 [0, 1, "james", "james", "james", 5, 6, 7, 8, 9]
    
    
    
    
    // -----------------------  for … of :遍历数组输出val or key ---------------------------------------------
    let arr=["Sephirex", "王思聪", "国名老公"];
    for (let item of arr){
        console.log(item);
    }
    // 输出Sephirex 王思聪 国名老公
    
    
    for (let key of arr.keys()){
        console.log(key);
    }
    // 输出0 1 2
    
    
    
    
    // -----------------------  entries( ) :遍历数组 ---------------------------------------------
    
    
    let arr=["Sephirex", "王思聪", "国名老公"];
    let list=arr.entries();
    console.log(list.next().value);
    console.log(list.next().value);
    console.log(list.next().value);
    // entries()实例方式生成的是Iterator形式的数组,在需要时可以用next()手动跳转到下一个值
    
    
    
    
    
    
    // -----------------------  数组的函数解构 ---------------------------------------------
    let arr=["Sephirex", "王思聪", "国名老公"];
    function fun(a, b, c){
        console.log(a, b, c);
    }
     
    fun(...arr);   // 控制台打印:Sephirex 王思聪 国名老公 ≈ 执行了 func([a, b, c] = [...arg])
    
    
    
    
    // ------------------------  in的用法   ----------------------------------------------
    // 对象判断:
    let obj={
        a:'jack',
        b:'马云'
    }
    console.log('a' in obj);  // true
    
    
    // 数组判断
    let arr=[,,,,,];
    console.log(arr.length); // 输出5,但是数组中其实全是空值
    
    
    // in方法:
    let arr=[,,,,,];
    console.log(0 in arr); // false
     
    let arr1=['jack','马云'];
    console.log(0 in arr1);  // true
    
    
    
    
    // ------------------------  数组遍历大法   ----------------------------------------------
    // 1.forEach()
    // 2.filter()
    // 3.some()
    // 4.map()
    
    
    
    
    // ------------------------  数组转字符串   ----------------------------------------------
    // 1.join()
    // 2.toString()
    
    
    
    


     

  6. 箭头函数和扩展

     =>不只是关键字function的简写,箭头函数与包围它的代码共享同一个 this,能帮你很好的解决this的指向问题。有经验的JavaScript开发者都熟悉诸如 var self = this;或 var that = this这种引用外围this的模式。但借助 =>,就不需要这种模式了。

    箭头函数的结构

    =>箭头之前:

                a. 一个空括号
                b. 单个的参数名
                c. 括号括起的多个参数名
    =>箭头之后:
                a. 一个表达式(作为函数的返回值)
                b. 用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)。

     

    ()=>1
    
    v=>v+1
    
    (a, b)=>a+b
    
    ()=>{
        alert("foo");
    }
    
    e=>{
        if (e == 0){
            return 0;
        }
        return 1000/e;
    }
    

     

  7. 对象

    对象赋值

    let name="Stephen";
    let skill= 'web';
    var obj= {name, skill};
    console.log(obj);  //Object {name: "Stephen", skill: "web"}


    对象Key值构建

    let key='skill';
    var obj={
        [key]:'web'   // 采用中括号形式进行对象构建
    }
    console.log(obj.skill);  // web


    自定义对象方法

    var obj={
        add:function(a,b){
            return a+b;
        }
    }
    console.log(obj.add(1,2));  // 3


    Object.is() 、 ==  和  ===

    var obj1 = {name:'jack'};
    var obj2 = {name:'jack'};
    console.log(obj1.name === obj2.name); // true
    console.log(Object.is(obj1.name, obj2.name)); //true
    
    
    console.log(2 == '2');  // true
    console.log(2 === '2');  // false
    console.log(+0 === -0);  // true
    console.log(NaN === NaN ); // false  NaN跟自身不等
    console.log(Object.is(+0,-0)); // false
    console.log(Object.is(NaN,NaN)); // true

    区别:==两边数据类型不同时自动先做类型转换,再进行比较,===为同值同类型相等,is()为严格相等
     

    Object.assign( )合并对象

    var a={a:'Sephirex'};
    var b={b:'王思聪'};
    var c={c:'国名老公'};
     
    let d=Object.assign(a, b, c)
    console.log(d);  // {a: "Sephirex", b: "王思聪", c: "国名老公"}

     

  8. Symbol

    let obj={name:'Stephen',skill:'web'};
    let age=Symbol();
    obj[age]=18;
    for (let item in obj){
        console.log(obj[item]);   // Stephen web
    } 
    console.log(obj); // {name: "Stephen", skill: "web", Symbol(): 18} 保护元素,隐藏年龄

     

  9. Set和Map

    Set声明

    let setArr = new Set(['Sephirex','王思聪','热狗','Sephirex']);
    console.log(setArr); // Set {"Sephirex", "王思聪", "热狗"}

    Set和Array区别:Set不允许内部有重复的值

    Set的相关操作

    let setArr = new Set(['Sephirex','王思聪','热狗','Sephirex']);
    console.log(setArr); // Set {"Sephirex", "王思聪", "热狗"}
    // --------------------------------------  add  -------------------------------------------------------------------
    setArr.add('真香');
    console.log(setArr);  // Set {"Sephirex", "王思聪", "热狗", "真香"}
    
    
    // --------------------------------------  delete  -------------------------------------------------------------------
    setArr.delete('真香');
    console.log(setArr); // Set {"Sephirex", "王思聪", "热狗"}
    
    
    // --------------------------------------  Retrieve  -------------------------------------------------------------------
    console.log(setArr.has('Sephirex')); //true
    
    
    // --------------------------------------  clear清空  -------------------------------------------------------------------
    setArr.clear();
    console.log(setArr) // Set {}
    
    
    // --------------------------------------  Set遍历: for of  -------------------------------------------------------------------
    for (let item of setArr){
        console.log(item);
    }
    
    
    // --------------------------------------  Set的size属性  -------------------------------------------------------------------
    console.log(setArr.size);   // 3
    
    
    // --------------------------------------  Set的forEach循环  -------------------------------------------------------------------
    setArr.forEach((value) => console.log(value));
    
    
    
    

    Json和Map:

    let json = {
        name:'Stephen',
        skill:'web'
    }
    console.log(json.name); // Stephen
     
    var map=new Map();
    map.set(json,'iam');
    console.log(map); 

    ES6后知后觉_第3张图片

    // --------------------------------------  获取json key对应value  -------------------------------------------------------------------
    console.log(map.get(json)); // iam
    
    
    // --------------------------------------  删除json key对应键值对  -------------------------------------------------------------------
    map.delete(json);
    console.log(map)   // Map {}
    
    
    // --------------------------------------  获取map size  -------------------------------------------------------------------
    console.log(map.size)  // 1
    
    
    // --------------------------------------  查找是否存在has  -------------------------------------------------------------------
    consolec .log(map.has('Stephen')) // true
    
    
    // --------------------------------------  清楚所有元素clear  -------------------------------------------------------------------
    map.clear()
    
    

     

     
  10. Proxy

    Proxy就像一个钩子函数,然你在对象与各种操作对象的行为之间收集与请求相作的各种信息,并返回任何你想做的。

    // --------------------------------------  ES5定义对象  -------------------------------------------------------------------
    var obj={
        add:function(val){
            return val+10;
        },
        name:'I am Stephen'
        
    };
    console.log(obj.add(100));  // 110
    console.log(obj.name);      // I am Stephen
    
    
    
    
    // --------------------------------------  声明Proxy  -------------------------------------------------------------------
    new Proxy({},{});   // 第一个花括号为方法的主体,第二个花括号为Proxy代理处理区域,相当于写钩子函数的地方。
    
    
    // --------------------------------------  改造传统定义对象方式  -------------------------------------------------------------------
    var pro = new Proxy({
        add: function (val) {
            return val + 10;
        },
        name: 'I am Stephen'
    }, {
        get:function(target, key, property){
            console.log('come in Get');
            return target[key];
       }
    });
     
    console.log(pro.name); 
    
    
    // 先输出 come in Get,这里相当于方法调用前执行的钩子
    // 再输出 I am Stephen
    
    
     

    get、set、apply用法

    get属性
    get属性是在你得到某对象属性值时预处理的方法,接收三个参数
    target:得到的目标值
    key:目标的key值,相当于对象的属性
    property:这个不太常用

    set属性
    set属性是值你要改变Proxy属性值时,进行的预先处理。接收四个参数。
    target:目标值。
    key:目标的Key值。
    value:要改变的值。
    receiver:改变前的原始值。


    apply
    在方法体是一个匿名函数时,调用内部的方法。

    var target = function () {
        return 'I am Stephen';
    };
    var handler = {
        apply(target, ctx, args) {
            console.log('do apply');
            return Reflect.apply(...arguments);
        }
    }
     
    var pro = new Proxy(target, handler);
     
    console.log(pro()); // 先输出do apply,再输出I am Stephen

     

     

  11. Promise

    Promise是异步编程的一种解决方案,比传统的解决方案callback更加的优雅。

    // -----------------------------------  举例日常海底捞吃饭  ------------------------------------------------------------------   
    let state=1;
    
    function step1(resolve, reject){
        console.log('1.开始-点菜');
        if(state==1){
            resolve('点菜--完成');
        }else{
            reject('点菜--出错');
        }
    }
     
    function step2(resolve, reject){
        console.log('2.开始-上菜吃饭');
        if(state==1){
            resolve('上菜吃饭--完成');
        }else{
            reject('上菜吃饭--出错');
        }
    }
     
    function step3(resolve, reject){
        console.log('3.开始-买单');
         if(state==1){
            resolve('买单--完成');
        }else{
            reject('买单--出错');
        }
    }
     
    new Promise(step1).then((val) => {
        console.log(val);
        return new Promise(step2);
    }).then((val) => {
        console.log(val);
        return new Promise(step3);
    }).then((val) => {
        console.log(val);
        return val;
    });
    
    
    // 这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步
    
    
    


     

  12. ES5中经常使用方法或者对象去模拟类的使用,虽然可以实现功能,但是代码并不优雅

    // -----------------------------------  类的声明  ------------------------------------------------------------------   
    class Coder{
        name(val){
            console.log(val);
        }
    }
    
    
    // -----------------------------------  类的使用  ------------------------------------------------------------------   
    let Sephirex = new Coder;
    Sephirex.name('思聪');  // 思聪
    
    // -----------------------------------  类的多方法声明  ------------------------------------------------------------------   
    class Coder{
        name(val){
            console.log(val);
            return val;
        }
        skill(val){
            console.log(this.name('Sephirex')+':'+'Skill:'+val);
        }
    }
     
    let Sephirex = new Coder;
    Sephirex.name('思聪');  // 思聪
    Sephirex.skill('web');  // this.name('Sephirex')调用内部方法打印并返回Sephirex   Sephirex:Skill:web
    
    
    
    
    // -----------------------------------  类的传参  ------------------------------------------------------------------   
    class Coder{
        name(val){
            console.log(val);
            return val;
        }
        skill(val){
            console.log(this.name('Sephirex')+':'+'Skill:'+val);
        }
     
        constructor(a, b){
            this.a=a;
            this.b=b;
        }
     
        add(){
            return this.a+this.b;
        }
    }
     
    let Sephirex = new Coder(1,2);
    console.log(Sephirex.add());  // 用constructor()进行传参。传递参数后可以直接使用this.xxx 进行调用,返回结果:3
    
    
    // -----------------------------------  类的继承  ------------------------------------------------------------------ 
    class Ceo extends Coder{
     
    }
    
    let shuaibi = new Ceo;
    shuaibi.name('巨超');
    
    



     

  13. 模块化

    ES5不支持原生的模块化,模块的功能主要由 export 和 import 组成。

    // ----------  export 把变量、函数、对象进行模块话,提供外部调用接口,让外部引用  --------------------------------------------------------
    // 新建一个文件tmp.js
    export var a = 'Sephirex';
    
    
    // 在index.js中引入a变量
    import {a} from './tmp.js';
    console.log(a);  // Sephirex
    
    
    // ----------  多变量输出  ---------------------------------
    var a ='Sephirex';
    var b ='王思聪';
    var c = '热狗';
     
    export {a, b, c}
    
    
    
    
    // ----------  函数模块化输出  -----------------------------
    export function add(a, b){
        return a+b;
    }
    
    
    // ----------  as的用法:不暴露源模块中的变量名  -----------------------------
    export {
        x as a,
        y as b,
        z as c
    }
    
    
    import {x, y, z} from './tmp';
    console.log(x,y,z)  // Sephirex 王思聪 热狗
    
    
    
    
    // ---------- export default一个文件中只能有一个  -----------------------------
    
    



     

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Js学习笔记)