15-ES6


typora-copy-images-to: media

ES6

变量声明let与const

  • let声明的变量不存在预解析

    console.log(flag);	// 会出错而不是undefined
    let flag = 123;
    
  • let声明的变量不允许重复(在同一个作用域内)

    let flag = 123;
    let flag = 456;	
    console.log(flag) // 会报错
    
  • 块内部定义的变量,在外部是不可以访问的

    ES6中的块:if(){块} for(){块} {块}

    if( true ){
        let uname = 'java';
    }
    console.log(uname); // 报错 ReferenceError: uname is not defined
    {
        let age = 13;
    }
    console.log(age);   // 报错 ReferenceError: age is not defined
    for (let i = 0; i < 3; i++) {
        // for循环括号中声明的变量只能在循环体中使用
        console.log(i);
    }
    console.log(i);
    
  • 在块级作用域内部,变量只能先声明再使用

    if(true){
        console.log(flag);	// 报错
        let flag = 123;
    }
    
  • const用来声明常量,const不允许重新赋值,const声明的常量必须初始化

变量的解构赋值

  • 数组的解构赋值

    let [a,b,c] = [1,2,3];	// 1 2 3
    let [a,b,c] = [,123,];	// undefined 123 undefined
    let [a=111,b,c] = [,123,];	// 111 123 undefined
    console.log(a,b,c);
    

  • 对象的解构赋值

    // 基础
    let {foo,bar} = {foo : 'hello',bar : 'hi'};
    let {foo,bar} = {bar : 'hi',foo : 'hello'};
    console.log(foo, bar); // hello hi
    
    // 对象属性别名(如果有了别名,那么原来的名字就无效了)
    let {foo:abc,bar} = {bar : 'hi',foo : 'nihao'};
    console.log(foo,bar); // 报错
    console.log(abc, bar); // 正确
    
    // 对象的解构赋值指定默认值
    let {foo:abc='hello',bar} = {bar : 'hi'};
    console.log(abc,bar);  // hello hi
    
    // Math是一个对象,所以也能被解构
    let {cos,sin,random} = Math;
    console.log(typeof cos);
    console.log(typeof sin);
    console.log(typeof random);
    

  • 字符串的解构赋值

    let [a,b,c,d,e] = "hello";
    console.log(a,b,c,d,e);  // h e l l o
    
    let {length} = "hi";
    console.log(length); // 2
    

字符串扩展

  • includes(子字符串, 开始位置) - 判断字符串中是否包含指定的字串(有的话返回true,否则返回false)

  • startsWith(子字符串) - 判断字符串是否以特定的字串开始

  • endsWith(子字符串) - 判断字符串是否以特定的字串结束

  • 模板字符串``

    // 字符串匹配
    console.log('hello world'.includes('world',7)); // false
    
    let url = 'admin/index.php';	
    console.log(url.startsWith('aadmin'));	
    console.log(url.endsWith('phph'));
    
    // 模板字符串
    let obj = {
        username : 'lisi',
        age : '12',
        gender : 'male'
    }
    let fn = function(info){
        return info;
    }
    let tpl = `
        <div>
            <span>${obj.username}</span>
            <span>${obj.age}</span>
            <span>${obj.gender}</span>
            <span>${1+1}</span>
            <span>${fn('nihao')}</span>
        </div>
    `;
    console.log(tpl);	// 解析后的html代码
    

函数扩展

  1. 参数默认值

    function foo(param = 'nihao'){
        console.log(param);
    }
    foo();	// nihao
    foo('hello kitty');	// hello kitty
    
  2. 参数解构赋值

    function foo({uname='lisi',age=13}={}){
        console.log(uname,age);
    }
    foo({uname:'zhangsan',age:15});
    
  3. ...rest参数(剩余参数)(位置:形参)

    function foo(a,b,...param){
        console.log(a);
        console.log(b);
        console.log(param); //[3,4,5]
    }
    foo(1,2,3,4,5);
    

  4. ...扩展运算符(位置:实参)

    function foo(a,b,c,d,e,f,g){
        console.log(a + b + c + d + e + f + g);
    }
    // foo(1,2,3,4,5);
    let arr = [1,2,3,4,5,6,7];
    // foo.apply(null,arr);
    foo(...arr);
    
    /* 合并数组 */
    let arr1 = [1,2,3];
    let arr2 = [4,5,6];
    let arr3 = [...arr1,...arr2];
    console.log(arr3);
    

  5. 箭头函数

    • 箭头函数中this取决于函数的定义,而不是调用
    • 箭头函数不可以new
    • 箭头函数不可以使用arguments获取参数列表,可以使用rest参数代替
    // --------------------
    let foo = () => console.log('hello');
    // 等同于
    function foo(){ console.log('hellio'); }
    
    // --------------------单个参数可以缩写,单行的return 可以省略
    let foo = v => v;
    // 等同于
    function foo(v){ return v; }
    
    // --------------------多个参数必须用小括号包住
    let foo = (a,b) => {let c = 1; console.log(a + b + c);}
    // 等同于
    function foo(a,b) { let c = 1; console.log(a + b + c); }
    
    // --------------------匿名函数
    arr.forEach((item, index) => { console.log(item, index); });
    // 等同于
    arr.forEach(function(item, index){ console.log(item, index); });
    

  6. 类与继承

    /* 类的定义 */
    class Animal{
        // 构造方法
        constructor(name){
            this.name = name;
        }
        // 静态方法(静态方法只能通过类名调用,不可以使用实例对象调用)
        static showInfo(){
            console.log('hi');
        }
        showName(){
            console.log(this.name);
        }
    }
    let a = new Animal('Tom');
    a.showName();	// 调用类中的方法
    Animal.showInfo();	// 调用静态方法
    
    /* 类的继承 */
    class Dog extends Animal{
      constructor(name, color){
        super(name);  // 调用父类中的构造方法
        this.color = color;
      }
      showColor(){
        console.log(this.color);
      }
    }
    let d = new Dog('jerry', 'red');
    d.showColor();	// 调用自身的方法
    d.showName();	// 调用父类的方法
    Dog.showInfo();  // 调用父类的静态方法
    

API

  • find(callback) - 回调查找第一个符合条件的数组元素
    • callback 查找的条件,返回一个布尔值
  • findIndex(callback) - 回调查找第一个符合条件的数组元素的索引
    • callback 查找的条件,返回一个布尔值

Promise

回调地狱

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在ES6中新增了一个API:Promise

解析Promise

  • Promise是一个构造函数
  • Promise容器一旦创建,就开始执行里面的代码
  • Promise本身不是异步的,它里面的任务才是异步的
/* 入门案例 */
const fs = require('fs');

// 创建Promise容器
// 1. 给别人一个承诺
console.log(1);
+ let p1 = new Promise(function(resolve, reject){
  console.log(2);
  fs.readFile('data/a.txt', 'utf8', function(err, data){
    if(err){
      //console.log(err);
      // 把容器的Pending状态改为 Rejected
+      reject(err);
    }else{
      console.log(3);
      //console.log(data);
      // 把容器的Pending状态改为 Resolved
+      resolve(data);
    }
  });
});
+ let p2 = new Promise(function(resolve, reject){
  console.log(2);
  fs.readFile('data/b.txt', 'utf8', function(err, data){
    if(err){
      //console.log(err);
      // 把容器的Pending状态改为 Rejected
+      reject(err);
    }else{
      console.log(3);
      //console.log(data);
      // 把容器的Pending状态改为 Resolved
+      resolve(data);
    }
  });
});
console.log(4);
// p1就是那个承诺的实例对象
// then中的第1个回调函数 对应 resolve(data)
// then中的第2个回调函数 对应 reject(err)
p1
+  .then(function(data){
  	console.log(data);
    // p1读取成功时,当前函数中 return 的结果可以在后面的 then 中的 function 回调函数中接收到,没有return 后面就接收到undefined
  	// 根据这个原理,我们可以 return 一个Promise对象
  	// 		当return一个Promise对象的时候,后面的then中的第一个回调函数会作为p2的 resolve,第二个回调函数会作为p2的 reject
+  	return p2;
+  },function(err){
  	console.log('读取文件失败', err);
  })
+  .then(function(data){
    console.log(data);
+    return p3;
  },function(err){
    console.log('读取文件失败', err);
  })
  
// 执行结果
1  2 4 3

封装Promise版的readFile

// 封装
var fs = require('fs');
function pReadFile(filePath){
  return new Promise(function(resolve, reject){
    fs.readFile(filePath, 'utf8', function(err, data){
      if(err)
        reject(err);
      else
        resolve(data);
    });
  });
}
// 调用
pReadFile('data/a.txt').then(function(data){
  return pReadFile('data/b.txt');
}).then(function(data){
  return pReadFile('data/c.txt');
})

Promise的应用场景

  • ajax同时查询多个数据表接口时,会出现嵌套情况,此时用Promise可以实现链式结构

封装Promise版的ajax


原文地址:https://www.cnblogs.com/pikachu/p/15211679.html