• ECMAScript 学习小结


    ECMAScript和JavaScript的关系是什么?

      前者是后者的规格,后者是前者的一种实现。日常场合,两者是可以互换不做分别的。

        ECMAScript 6 即是ECMAScript的第 6 个版本。

     

    let和const命令

      let和const命令:

        let用来声明变量,用法类似于var,但是也有很大的差别。

          const用来声明常量,常量是必须声明后立即赋值的,不可以后续赋值也不可以后续更改值,

            否则会报错。const的其他特点和let基本一致。

              let的变量声明和赋值是同步进行,是不会提前声明的,不挂载到window上的,

                在let声明执行之前也是不可以对let声明的变量进行任何操作的。

     

    console.log(b);     //2    
    console.log(a);     //报错,提示a不存在
    
    let a = 1;
    var b = 2;

     

        let、const声明的变量名不可以重复声明。

    let a = 1;
    var a = 2;
    //直接报错
    
    let a = 1;
    function a(){
        var a = 2;
    }
    //直接报错

        let、const声明只在let命令所在的代码块内有效。

    {
        let a = 10;
        var b = 1;
    }
    
    console.log(b);      //1
    console.log(a);      //报错

        for循环中循环表达式很适合用let命令。也进一步证明let命令只在代码块中有效。

    for(var i=0;i<10;i++){}
    console.log(i)      //10
    
    for(let j=0;j<10;j++){}
    console.log(j)      //报错

        

    var a = [];
    for (var i = 0; i < 10; i++) {
        a[i] = function () {
            console.log(i);
        };
    }
    a[6]();       //10     

        以上代码因为var为全局变量赋值,在全局范围内有效且只有一个i,每一次循环i的值都会发生改变,最终累加到10停止循环。

          而for循环内部的console.log( i ),这里的i值在函数内找不到就只能去父级寻找,最终找到已经累加到10的i,进行输出,所以输出为10。

            那么怎样才能使其输出对应下标里的i值呢?

    var a = [];
    for (let i = 0; i < 10; i++) {
        a[i] = function () {
            console.log(i);
        };
    }
    a[6]();  //6

        以上代码使用了let来声明变量i,所以i只在块级作用域内有效,而且是本轮循环内有效,所以每次循环的i值都为在一个块级作用域内一个独立的变量。

          而每次循环i能记住上一个i的值,是因为JavaScript内部进行的操作,引擎内部会记住上一轮循环的值,在上一轮循环的基础上进行计算。

            除了上一种方法,还有一种采用闭包的方法。

    var arr = [];
    for (var i = 0; i < 10; i++) {
        (function(i){
            arr[i] = function(){
            console.log(i)
            }
        }(i))
    }
    arr[8]();      //8

        let和const的临时死区

          只要块级作用域内存在let和const命令,它所声明的变量就绑定这个区域,不再受外部的影响。

    ES7中的...运算符

      多用于调用函数和对象:

    function abc(a,b,c){
      console.log(a+b+c);
    }
    var arr = [3,4,5];
    abc(...arr)

      该运算符将一个数组变为参数序列。运算符也可以和正常的函数参数结合使用。

    function abc(a,b,c,d){
        console.log(a+b+c+d);
    }
    var arr = [3,4,5];
    abc(2,...arr);

       可以通过该运算符来达到克隆的效果。

        浅克隆:

    let a = {
        num : 1 
    }
    let b = {
        num : 2
    }
    let c = {
        ...a,
        ...b        
    }    

        深克隆

    let a = {
        num : 1 
    }
    let b = {
        num : 2
    }
    let c = {
        num : {
            ...a,
            ...b
        }     
    }  

    解构赋值

      解构一个数组

    let arr = [1,2,3];
    let x,y,z;
    [x,y,z] = arr;
    //x = 1;y = 2;z = 3;

      解构一个对象

    let obj = {
        name : "Tom",
        age : 18,
        sex : "0"
    }
    let name,age,sex;
    ({name,age,sex} = obj )
    //name = "Tom";age = 18;sex = "0";

    箭头函数

      ES6 允许使用“箭头”(`=>`)定义函数。可以非常简洁的写函数。

    var sum  = function(a,b){
        return a+b;  
    }
    //等同于
    let sum  = (a,b) =>{
        return a+b;  
    }
    var fun = function(a,b){
        return {
            a:a,b:b
        }
    }
    //等同于
    let fun = (a,b) => {
        return {
            a : a,
            b : b 
        }
    }        
    function fun(x){
        return function(y){
            return function(z){
                return x+y+z;
            }
        }
    }        
    //等同于
    let fun = x => y => z => x+y+z;

    Map 结构

      Map数据结构类似于对象,就是用来存储内容的。

        首先来用Map方法来创建一个集合。

    var map = new Map();
    map.a = 1;
    map.b = 2;
    map.c = 3;
    map.set("0","html");
    map.set("1","css");
    map.set("2","JavaScript");

    map.get("0");//"html"
    map.get("0");//true

         这个map数据集合可以使用set方法为其中添加一个键值,也可以用get方法获取到这个值。也可以使用delete方法来删除选择的键值。

      作为构造函数,Map也可以接受一个数组作为参数。

    var map = new Map([['name','张三'],['age','20']]);
    //等同于set('name','张三');

     实例的属性和操作方法

      size属性

        size属性返回Map结构的成员总数

    let map = new Map();
    map.set("name","Tom");
    map.set("age","20");
    
    map.size    //2

      Map.set(key,value)

        set方法设置属性名key对应的属性值为value,然后返回整个Map结构。如果key已经有值,则属性值会被更新,否则就新生成该属性。

    let map = new Map();
    
    map.set("key",10);    //属性名是字符串,值为数字
    map.set(110,"120");    //属性名是数字,值为字符串
    map.set(undefined,"haha")    //属性名为undefined,值为字符串

    //可以使用链式写法
    map.set(1,"a")
      .set(2,"b")
      .set(3,"c");

      Map.get(key)

        get方法读取key对应的属性值,如果找不到key,则返回undefined

    function fun(){console.log("Hello world!!!");}
    let map = new Map()
        .set(fun,"Hello");
    
    map.get(fun);    //会调用到该函数,输出"Hello world !!!"
    map.get(haha);  //undefined

      Map.delete(key)

        delete方法删除某个属性,返回true。如果删除失败,则返回false

    function fun(){console.log("Hello world !!!");}
    let map = new Map().set(fun,"Hello world")
    
    map.delete(fun);    //true
    map.delete(fun);    //false

      Map.clear()

        clear方法清除所有成员,没有返回值。

    let map = new Map();
    map.set(1,1);
    map.set(2,2);
    
    map.clear();

    Map的循环遍历

      for of

    var map = new Map([['name','张三'],['age','20']]);
    //等同于set('name','张三');
    for(var i in map){
        console.log(i)
    }
    //输出map对象下标名
    for(var index of map){
        console.log(index);
    }
    //输出添加进去的键值对的数组
    for(var name of map.entries()){
        console.log(name)
    }
    //输出对应的键值对
    for (var [key,value] of map.entries()){
        console.log(key,value)
    }
    //输出对应键值对
    for (var val of map.values()){
        console.log(val)
    }
    //输出键值对的值

    class

      ES 6 的类完全可以看做构造函数的另一种写法。其数据类型就是函数。

    class Hyh{}
    typeof Hyh; //"function"

      使用的时候也是直接对lei使用new命令,和构造函数的用法完全一致。

    class ID{
        constructor(name,age){
            this.name = name;
            this.age = age;  
        }
        logFun(){
            console.log("name:"+this.name+"
    "+"age:"+this.age);
        }
    }
    
    var Tom = new ID("Tom",21);
    Tom.name    //"Tom"
    Tom.age    //21
    
    Tom.logFun();     
    //name:Tom
    //age:21

      Tom是ID的实例,Tom的constructor方法就是ID类原型的constructor方法,可以在类的prototype上添加类的新方法。可以通过Object.assign方法一次向类添加多个方法。

    Object.assign(ID.prototype,{
        toName(){},
        toAge(){} 
    })

    class的继承

      class可以通过extends关键字实现继承

    class Code extends ID{}

      继承后可以调用继承来的方法和属性

    var Jack = new Code("Jack","20");
    Jack.name;    //"Jack"
    Jack.logFun();
    //name:Jack
    //age:20

      也可以继承父类函数后再在自身添加新的属性和参数,通过super方法接收父类构造的参数信息

    class ID{
        constructor(name,age){
            this.name = name;
            this.age = age;  
        }
        logFun(){
            console.log("name:"+this.name+"
    "+"age:"+this.age);
        }
    }
    
    class Code extends ID{
        constructor(name,age,color){
            super(name,age);    //用来继承父类参数接收
            this.color=color
        }
    }
    
    var color = new Code("Jack","20","black")


    Promise对象  承诺

      它是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。主要用来做异步的消息处理的。

      它就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。

    Promise对象的两个特点:

      1、对象的状态不受外界的影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、funlfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

      2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为funlfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就成为resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果,这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

    基本用法

      Promise对象是一个构造函数,用来生成Promise实例。

    let promise = new Promise(function(resolve,reiect){
        if("如果异步操作成功"){
            resolve(value);    //执行resolve成功函数
        }else{
            reject(error);    //执行reject失败函数
        }
    })

      Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve失败函数和reject成功函数。它们是两个函数,由JavaScript引擎提供,不用自己部署。

      resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从pending变为resolved),再异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从pending变为rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

    then()方法

      Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的毁掉函数。

    promise.then(function(value){
        console.log("成功了!"+value);
    },function(error){
        console.log("失败了!"+error);
    })

      then调用以后又返回一个Promise对象。这时可以链式写法在新的Promise上写then方法,这个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化。

    promise.then(function(data){
        return data + 10;
    },function(){
    }).then(function(data){
        console.log(data);
    },function(err){
        console.log(err); 
    })

      利用Promise写一个ajax

    var btn = document.getElementById("btn");
    var box = document.getElementById("box");
    
    btn.onclick = function(){
        var promise = new Promise(function(resolve,reject){
            ajax('./16.txt',function(data){
                resolve(data)
            },function(err){
            reject(err)
            })
        })
        promise.then(function(data){
            box.innerHTML = data;
        },function(err){
            box.innerHTML = err;
        })
    }
    
    function ajax(url,fnSucc,fnErr){
        var xhr = new XMLHttpRequest();
        xhr.open('GET',url,true);
        xhr.send();
        xhr.onload = function(){
            if(xhr.readyState == 4 && xhr.status == 200){
            fnSucc(xhr.responseText);
            }else{
            fnErr(xhr.status);
            }
        }
    }        

       

  • 相关阅读:
    解决IE8下VS2005,VS2008一些向导提示脚本错误问题
    12-7
    12.4
    写在十一月的尾巴
    11.28
    htm&css 颜色的浮动
    11.27
    11.26
    html基础——表格练习
    html基础——div/span
  • 原文地址:https://www.cnblogs.com/yeming980912/p/11270958.html
Copyright © 2020-2023  润新知