• vue项目开发前的es6的知识储备


     let命令 学习笔记

    1、let所声明的变量,只在let命令所在的代码块内有效。

    2、不存在变量提升:所声明的变量一定要在声明后使用,否则报错。

      一定要先声明,再去使用。let x=x;这样就是错误的

    ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

     3、不允许重复声明:let不允许在相同作用域内,重复声明同一个变量。即不能在函数内部重新声明参数。

    块级作用域

    1、为什么需要块级作用域?

      ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
      第一种场景,内层变量可能会覆盖外层变量。

    var tmp = new Date();
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = 'hello world';
      }
    }
    f(); // undefined

      第二种场景,用来计数的循环变量泄露为全局变量。下面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量

    var s = 'hello';
    for (var i = 0; i < s.length; i++) {
      console.log(s[i]);
    }
    console.log(i); // 5

    2、ES6 的块级作用域:外层作用域无法读取内层作用域的变量。内层作用域可以定义外层作用域的同名变量。

      下面的函数有两个代码块,都声明了变量n,运行后输出5。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是10。

    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
        console.log(n);
      }
      console.log(n); // 5
    }
    f1()

       块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

    // IIFE 写法
    (function () {
      var tmp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let tmp = ...;
      ...
    }

      块级作用域用法:考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句

    // 函数声明语句
    {
      let a = 'secret';
      function f() {
        return a;
      }
    }
    
    // 函数表达式
    {
      let a = 'secret';
      let f = function () {
        return a;
      };
    }

      ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

    3、do 表达式 

      本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。想要解决方法:使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上do,使它变为do表达式,然后就会返回内部最后执行的表达式的值。

    let x = do {
      let t = f();
      t * t + 1;
    };

     const 命令

      const声明一个只读的常量。一旦声明,常量的值就不能改变。const一旦声明变量,就必须立即初始化,不能留到以后赋值。

      const的作用域与let命令相同:只在声明所在的块级作用域内有效。

       const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

      const声明的常量,也与let一样不可重复声明。

    箭头函数

      1、省略了function,花括号‘{}’用‘=>’代替了。这种写法更简洁了。

      2、优点,就是函数体内的this的指向始终是指向定义它所在的对象,而不会指向调用它的对象,我们知道es5中的函数是谁执行它,它就指向谁。

      参考:es6箭头函数讲解   es6学习笔记10--箭头函数

    ES6---数组array新增方法 

       参考:http://blog.csdn.net/wbiokr/article/details/65939582

    Promise 对象

      一、Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。Promise对象是一个构造函数,用来生成Promise实例.

        补充知识:与 ‘new’ 运算符一起使用用来创建对象并初始化对象的‘函数’就是构造函数; 实例化(在面向对象的编程中,通常把用类创建对象的过程称为实例化。)对象就是创建对象的过程!

    var request = new XMLHttpRequest();

        “new XMLHttpRequest();” 这句话就是一个标准的构造函数!我们 “var” 声明了一个 “request” 对象,用构造函数 “new XMLHttpRequest();” 来初始化这个 “request” 对象为它赋初始值。

      所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

      二、Promise对象有以下两个特点。

           (1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

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

      Promise对象有缺点:

      1,无法取消Promise,一旦新建它就会立即执行,无法中途取消。

      2,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

      3,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

      下面代码创造了一个Promise实例。

    var promise = new Promise(function(resolve, reject) {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });

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

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

    promise.then(function(value) {
      // success
    }, function(error) {
      // failure
    });

     下面是一个Promise对象的简单例子。

    function timeout(ms) {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done');
      });
    }
    
    timeout(100).then((value) => {
      console.log(value);
    });

      上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。一般情况不调用setTimeout指定时间,Promise 新建后就会立即执行。

    三、Promise.prototype.then()

      then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

    getJSON("/post/1.json").then(function(post) {
      return getJSON(post.commentURL);
    }).then(function funcA(comments) {
      console.log("resolved: ", comments);
    }, function funcB(err){
      console.log("rejected: ", err);
    });

    上面代码中,第一个then方法指定的回调函数,返回的是另一个Promise对象。这时,第二个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化。如果变为resolved,就调用funcA,如果状态变为rejected,就调用funcB。如果采用箭头函数,上面的代码可以写得更简洁。

    getJSON("/post/1.json").then(
      post => getJSON(post.commentURL)
    ).then(
      comments => console.log("resolved: ", comments),
      err => console.log("rejected: ", err)
    );

    四、Promise.prototype.catch()

      Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

    getJSON('/posts.json').then(function(posts) {
      // ...
    }).catch(function(error) {
      // 处理 getJSON 和 前一个回调函数运行时发生的错误
      console.log('发生错误!', error);
    });

      上面代码中,getJSON方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数,处理这个错误。另外,then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。

    getJSON('/post/1.json').then(function(post) {
      return getJSON(post.commentURL);
    }).then(function(comments) {
      // some code
    }).catch(function(error) {
      // 处理前面三个Promise产生的错误
    });

      Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

      一般来说,不要在then方法里面定义Reject状态的回调函数(即then的第二个参数),总是使用catch方法。

    // bad
    promise
      .then(function(data) {
        // success
      }, function(err) {
        // error
      });
    
    // good
    promise
      .then(function(data) { //cb
        // success
      })
      .catch(function(err) {
        // error
      });

      上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。

    const someAsyncThing = function() {
      return new Promise(function(resolve, reject) {
        // 下面一行会报错,因为x没有声明
        resolve(x + 2);
      });
    };
    
    someAsyncThing().then(function() {
      console.log('everything is great');
    });
    
    setTimeout(() => { console.log(123) }, 2000);
    // Uncaught (in promise) ReferenceError: x is not defined
    // 123

      上面代码中,someAsyncThing函数产生的 Promise 对象,内部有语法错误。浏览器运行到这一行,会打印出错误提示ReferenceError: x is not defined,但是不会退出进程、终止脚本执行,2秒之后还是会输出123。这就是说,Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。

      一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法

    五、Promise.all() 

      Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

       var p = Promise.all([p1, p2, p3]); 

      Promise.all方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。

      p的状态由p1、p2、p3决定,分成两种情况:
        (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
        (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

    六、Promise.race()

      Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。

       var p = Promise.race([p1, p2, p3]); 上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    七、Promise.resolve() 

      有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用。

    八、模块语法

      1、ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

      ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入

    // ES6模块
    import { stat, exists, readFile } from 'fs';

      上面代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。

      2、严格模式

      • 变量必须声明后再使用
      • 函数的参数不能有同名属性,否则报错
      • 不能使用with语句
      • 不能对只读属性赋值,否则报错
      • 不能使用前缀0表示八进制数,否则报错
      • 不能删除不可删除的属性,否则报错
      • 不能删除变量delete prop,会报错,只能删除属性delete global[prop]  
      • eval不会在它的外层作用域引入变量
      • evalarguments不能被重新赋值
      • arguments不会自动反映函数参数的变化
      • 不能使用arguments.callee
      • 不能使用arguments.caller
      • 禁止this指向全局对象
      • 不能使用fn.callerfn.arguments获取函数调用的堆栈
      • 增加了保留字(比如protectedstaticinterface

      尤其需要注意this的限制。ES6 模块之中,顶层的this指向undefined,即不应该在顶层代码使用this。

      3、export 命令

      模块功能主要由两个命令构成:exportimportexport命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

      一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。

    // profile.js
    var firstName = 'Michael';
    var lastName = 'Jackson';
    var year = 1958;
    
    export {firstName, lastName, year};

       export命令除了输出变量,还可以输出函数或类(class)。下面代码对外输出一个函数multiply

    export function multiply(x, y) {
      return x * y;
    };

      export输出的变量就是本来的名字,但是可以使用as关键字重命名。

    function v1() { ... }
    function v2() { ... }
    
    export {
      v1 as streamV1,
      v2 as streamV2,
      v2 as streamLatestVersion
    };

      上面代码使用as关键字,重命名了函数v1v2的对外接口。重命名后,v2可以用不同的名字输出两次。需要特别注意的是export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

    // 写法一
    export var m = 1;
    
    // 写法二
    var m = 1;
    export {m};
    
    // 写法三
    var n = 1;
    export {n as m};

      上面三种写法都是正确的,规定了对外的接口m。其他脚本可以通过这个接口,取到值1。它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系。functionclass的输出,也必须遵守这样的写法。

       另外,export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

    export var foo = 'bar';
    setTimeout(() => foo = 'baz', 500);

      上面代码输出变量foo,值为bar,500毫秒之后变成bazexport命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错

      3、import 命令

      使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

    // main.js
    import {firstName, lastName, year} from './profile';
    
    function setName(element) {
      element.textContent = firstName + ' ' + lastName;
    }

      import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。

  • 相关阅读:
    答题卡
    hdu 5451 Best Solver
    L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛)
    MicroRNA Ranking(Tehran2016)
    Split The Tree(2018东北四省赛)
    Django项目基础开发流程
    暑假学习进度记录墙
    抖音字体设置
    十大危险cmd指令
    奶牛的聚会
  • 原文地址:https://www.cnblogs.com/untiring/p/7767776.html
Copyright © 2020-2023  润新知