美文网首页
ES5 6 7常用语法

ES5 6 7常用语法

作者: 冬来Angus | 来源:发表于2018-07-26 18:39 被阅读0次

    ECMAScript

    简介

    1. 它是一种由ECMA组织(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范
    2. 而我们学的JavaScript是ECMA的实现, 但术语ECMAScript和JavaScript平时表达同一个意思
    3. JS包含三个部分:
      1. ECMAScript(核心)

      2. 浏览器端扩展

        1. DOM(文档对象模型)
        2. BOM(浏览器对象模型)
      3. 服务器端扩展

        Node

    4. ES的几个重要版本
      1. ES5 : 09年发布
      2. ES6(ES2015) : 15年发布, 也称为ECMA2015
      3. ES7(ES2016) : 16年发布, 也称为ECMA2016 (变化不大)
    5. 扩展学习参考:
      1. ES5 :
      2. ES6
      3. ES7

    严格模式("use strict")

    • 运行模式:
      • 正常(混杂)模式
      • 严格模式
    • 应用上严格式:
      • 'strict mode';
    • 作用:
      • 使得Javascript在更严格的条件下运行
      • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为
      • 消除代码运行的一些不安全之处,保证代码运行的安全
    • 需要记住的几个变化
      • 声明定义变量必须用var
      • 禁止自定义的函数中的this关键字指向全局对象
      • 创建eval作用域,更安全
      • 对象不能有重名属性

    ES5 常用方法

    JSON对象

    • 作用: 用于在json对象/数组与js对象/数组相互转换
    • JSON.stringify(obj/arr)
      js对象(数组)转换为json对象(数组)
    • JSON.parse(json)
      json对象(数组)转换为js对象(数组)

    Object扩展

    • Object.create(object, prototype[descriptors]):
      • 创建一个新的对象
        • 以指定对象为原型创建新的对象
        • 指定新的属性, 并对属性进行描述
    var o = {
        username: 'xiaoming',
        age: 20
    };
    var obj = Object.create(o, {
        sex: {
            value: '男',//指定值
            writable: true,//标识当前属性值是否是可修改的, 默认为false
            configurable: true,//标识当前属性值是否是可以被删除, 默认为false
            enumerable: true //标识当前属性能否用 for in 枚举,默认为false
        }
    });
    
    • Object.defineProperties(object, descriptors):
      • 为指定对象定义扩展多个属性
      • get方法 : 用来获取当前属性值的回调函数
      • set方法 : 用来监视当前属性值变化的回调函数,实参即为修改后的值
      • 存取器属性: setter,getter 一个用来存值,一个用来取值
    var o = {
        firstName: 'Xiaoming',
        lastName: 'Wang'
    };
    var obj = Object.defineProperties(o, {
        fullName: {
            get: function () {//获取扩展属性的值,获取拓展属性值是get方法自动调用(惰性求值)
                return this.firstName + ' ' + this.lastName;
            },
            set: function (data) {//监听扩展属性,当扩展属性发生变化的时候自动调用
                var names = data.split(' ');
                this.firstName = names[0];
                this.lastName = names[1];
            }
        }
    });
    
    • 对象本身就有 get 和 set 方法:
    var obj = {
        firstName: 'Xiaoming',
        lastName: 'Wang',
        get fullName() {//get 获取的值不能直接obj.fullName修改
            return this.firstName + ' ' + this.lastName;
        },
        set fullName(data) {
            var names = data.split(' ');
            this.firstName = names[0];
            this.lastName = names[1];
        }
    };
    

    ES6 常用语法

    2个新的关键字

    1. let
    • 声明一个变量
    • 在块级作用域内有效
    • 不能重复声明
    • 不会预处理,不存在变量提升
    1. const
    • 定义一个常量
    • 不能修改
    • 其他同 let

    变量的解构赋值

    • 从对象或数组中提取数据,并赋值给多个变量
    • 数据源:
      • 对象let {a, b} = {a: "a", b: "b"}
      • 数组let [a, b] = ['a', 'b']
    let o = {
        firstName: 'Xiaoming',
        lastName: 'Wang'
    };
    //解构对象必须以对象形式解构
    //必须赋值对象已有属性
    let {firstName, lastName} = o;
    console.log(firstName, lastName);//Xiaoming Wang
    
    let arr = [1, 'a', true];
    //解构数组必须以数组形式解构
    //根据数组下标取值,不需要的则以逗号占位
    let [, a, b, c] = arr;
    console.log(a, b, c);//a true undefined
    let [d, ...e] = arr;
    console.log(d, e);//1 ["a", true]
    
    function fun ({firstName, lastName}) {//{firstName, lastName} = o
        console.log(firstName, lastName);//Xiaoming Wang
    }
    

    各种数据类型的扩展

    • 字符串

      • 模板字符串
        • 作用: 简化字符串的拼接
        • 模板字符串必须用``
        • 变化的部分使用${xxx}定义
      • contains(str): 判断是否包含指定的字符串
      • startsWith(str) : 判断是否以指定字符串开头
      • endsWith(str): 判断是否以指定字符串结尾
      • repeat(count) : 重复指定次数
    • 对象

      • 简化的对象写法
        let name = 'Tom';
        let age = 12;
        let person = {
            name,//同名属性可以省略不写 name: name
            age,
            setName (name) {
                this.name = name;
            }
        };
        
      • Object.assign(target, source1, source2..) : 将源对象的属性复制到目标对象上
      • Object.is(v1, v2) : 判断2个数据是否完全相等
      • proto属性 : 隐式原型属性
    • 数组

      • Array.from(v): 将伪数组对象或可遍历对象转换为真数组
      • Array.of(v1, v2, v3): 将一系列值转换成数组
      • find(function(value, index, arr){return true}): 找出第一个满足条件返回true的元素
      • findIndex(function(value, index, arr){return true}): 找出第一个满足条件返回true的元素下标
    • 函数

      • 箭头函数

        • 用来定义匿名函数
        • 基本语法:
          • 没有参数: () => console.log('xxxx')
          • 一个参数:i => i+2
          • 大于一个参数: (i, j) => i+j
          • 函数体不用大括号: 默认返回结果
          • 函数体如果有多个语句, 需要用{}包围
          • 箭头函数的this不是调用时决定的,而是在定义的时候处在的对象就是它的this
          • 箭头函数的this看外层是否有函数,有,则其this为外层函数的this;没有,则其thiswindow
        • 使用场景: 多用来定义回调函数
      • 形参的默认值

        • 定义形参时指定其默认的值
        function Point (x = 0, y = 0) {
            this.x = x;
            this.y = y;
        }
        let point = new Point(21, 22);//Point {x: 21, y: 22}
        let oPoint = new Point();//Point {x: 0, y: 0}
        
      • rest(可变)参数

        • 通过形参左侧的...来表达, 取代arguments的使用
        function fun (a, ...values) {//...values只能放在最后
            values.forEach((i, v) => {//values是一个真数组
                console.log(i, v)
            });
        }
        
      • 扩展运算符(...)

        • 可以分解出数组或对象中的数据
        let arr = [2, 3, 4, 5, 6];
        arr1 = [1, ...arr, 7];
        console.log(arr1);//[1, 2, 3, 4, 5, 6, 7]
        

    set/Map容器结构

    • 容器: 能保存多个数据的对象, 同时必须具备操作内部数据的方法

    • 任意对象都可以作为容器使用, 但有的对象不太适合作为容器使用(如函数)

    • Set的特点: 保存多个value, value是不重复( 数组元素去重)

    • Map的特点: 保存多个key-value, key是不重复, value是可以重复的

    • API

      • Set容器 : 无序不可重复的多个value的集合体

        • Set()/Set(arr) //arr是一维数组
          • add(value)
          • delete(value)
          • has(value)
          • clear()
          • size
        • set转化为数组:
          • [...set]
          • ``Array.from(set)`
        • 数组去重:Array.from(new Set(arr));
      • Map容器 : 无序的 key不重复的多个key-value的集合体

        • Map()/Map(arr) //arr是二维数组
          • set(key, value)
          • get(key)
          • delete(key)
          • has(key)
          • clear()
          • size

    Promise

    • 解决回调地狱(回调函数的层层嵌套, 编码是不断向右扩展, 阅读性很差)

    • 能以同步编码的方式实现异步调用

    • ES6之前原生的js中是没这种实现的, 一些第三方框架(jQuery)实现了promise

    • Promise是一个构造函数,用来生成promise实例

    • 存在三个状态

      • pending:初始化状态
      • fullfilled:成功状态
      • rejected:失败状态
    • ES6中定义实现API:

      function getDatas (url) {
          //初始化 promise 状态: pending
            //执行异步操作
          //创建 xmlHttp 实例对象
          let promise = new Promise((res, rej) => {
              let xhr = new XMLHttpRequest();
              //绑定监听
              xhr.onreadystatechange = function () {
                  if (xhr.readyState === 4) {
                      if (xhr.status === 200) {//请求成功,调用成功的回调
                          res(xhr.responseText);
                      } else {//请求失败,调用失败的回调
                          rej(error);
                      }
                  }
              };
              //设置请求方式及url
              xhr.open('GET', url)
          });
          return promise;
      }
      //调用
      getDatas('http://localhost:8080/datas')
          .then((data) => {
            console.log(data);
          }, (error) => {
            console.log(error);
          });
      

    Symbol

    概念:

    ES6中的添加了一种原始数据类型symbol

    特点:

    1. Symbol属性对应的值是唯一的,解决命名冲突问题
    2. Symbol值不能与其他数据进行计算,包括同字符串拼串
    3. for in, for of遍历时不会遍历symbol属性。

    使用:

    1. 调用Symbol函数得到symbol

      let symbol = Symbol();
      let obj = {};
      obj[symbol] = 'hello';
      console.log(obj);//{Symbol(): "hello"}
      
    2. 传参标识

      let symbol = Symbol('one');
      let symbol2 = Symbol('two');
      console.log(symbol);// Symbol('one')
      console.log(symbol2);// Symbol('two')
      
    3. 内置Symbol

      除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法

    4. Symbol.iterator

      • 对象的Symbol.iterator属性,指向该对象的默认遍历器方法
      let targetData = {
          //等同于在指定的数据内结构上部署了 iterator 接口
          //当 for of 去遍历某一个数据结构的时候,首先去找 Symbol.iterator
          [Symbol.iterator]: function () {
             let nextIndex = 0,
              len = this.length;
              return {//遍历器对象
                  next: function () {
                      return {
                          value: this[nextIndex++],
                          done: nextIndex < len ? false : true
                      }
                  }
              } 
          }
      }
      

    iterator

    概念:

    iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制。
    作用:

    1. 为各种数据结构,提供一个统一的、简便的访问接口
    2. 使得数据结构的成员能够按某种次序排列
    3. ES6创造了一种新的遍历命令for of循环,iterator接口主要供for of消费。

    工作原理:

    • 创建一个指针对象(遍历器对象),指向数据结构的起始位置
    • 第一次调用next方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用next`方法,指针会一直往后移动,直到指向最后一个成员
    • 每调用next方法返回的是一个包含valuedone的对象,{value: 当前成员的值,done: 布尔值}
    • value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束
    • 当遍历结束的时候返回的value值是undefineddone值为false
    //模拟指针对象(遍历器对象)
    function myIterator (arr) {//iterator接口
        let nextIndex = 0,
            len = arr.length;
        return {//遍历器对象
            next: function () {
                return {
                    value: arr[nextIndex++],
                    done: nextIndex < len ? false : true
                }
            }
        }
    }
    //准备一个数据
    let arr = [1, 2, 23, 'abc'];
    let iteratorObj = myIterator(arr);
    

    原生具备iterator接口的数据(可用for of遍历)

    • Array
    let arr = [1, 2, 23, 'abc'];
    for(let i of arr) {
        console.log(i);
    }
    
    • arguments
    function fun () {
        for(let i of arguments) {
            console.log(i);
        }
    }
    fun(1, 2, 23, 'abc');
    
    • set容器
    • map容器
    • String

    其他:

    • 对象不具备 iterator 接口,故不可用 for of遍历
    var o = {
        username: 'Tom',
        age: 23
    }
    for (let i of o) {
        console.log(i);//Uncaught TypeError: o is not iterable
    }
    //添加遍历器
    o[Symbol.iterator] = function* test() {
        yield 1
    }
    for (let i of o) {
        console.log(i);//1
    }
    
    • 使用三点运算符、结构赋值,默认调用iterator接口

    for--of循环

    • 遍历数组
    • 遍历Set
    • 遍历Map
    • 遍历字符串
    • 遍历伪数组

    Generator

    概念:

    1. ES6提供的解决异步编程的方案之一
    2. Generator函数是一个状态机,内部封装了不同状态的数据,用来生成遍历器对象
    3. 可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果

    特点:

    1. function 与函数名之间有一个星号
    2. 内部用yield表达式来定义不同的状态
    function* generatorExample(){
        yield 'hello';  // 状态值为hello
        yield 'generator'; // 状态值为generator
        return "result"
    }
    let a = generatorExample();
    a.next();//{value: "hello", done: false}
    a.next();//{value: "generator", done: false}
    a.next();//{value: "result", done: true},有 return 返回值则为返回值,无返回值为 undefined
    a.next();//{value: undefined, done: true}
    
    1. Generator函数返回的是指针对象(iterator),而不会执行函数内部逻辑
    2. 调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}
    3. 再次调用next方法会从上一次停止时的yield处开始,直到最后
    4. yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。
    function* generatorExample(){
        let a = yield 'hello';  // 状态值为hello
        console.log(a);//a的值为 undefined
        yield 'generator'; // 状态值为generator
    }
    let a = generatorExample();
    a.next();//{value: "hello", done: false}
    a.next("para");//a的值变为传入的 ‘para’;//{value: generator, done: true}
    

    class类

    • class定义一类
    • constructor()定义构造方法(相当于构造函数)
    • 一般方法: xxx () {}
    //定义父类
    class Person {
        //类的构造方法
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        //类的一般方法
        showInfo() {
            console.log(this.name, this.age);
        }
    }
    let person = new Person('Tom', 23);
    console.log(person);//Person {name: "Tom", age: 23}
    person.showInfo();//Tom 23
    
    • extends来定义子类

    • super()来父类的构造方法

    • 子类方法自定义: 将从父类中继承来的方法重新实现一遍

    • js中没有方法重载(方法名相同, 但参数不同)的语法

    //定义子类
    class SubPerson extends Person {
        constructor(name, age, salary) {
            super(name, age);//调用父类的构造方法
            this.salary = salary;
        }
        //重写父类的方法
        showInfo() {
            console.log(this.name, this.age, this.salary);
        }
    }
    let sub = new SubPerson('Jack', 13, 10000);
    console.log(sub);//SubPerson {name: "Jack", age: 13, salary: 10000}
    sub.showInfo();//Jack 13 10000
    

    ES7

    async函数(源自ES2017)

    概念:

    ​ 真正意义上去解决异步回调的问题,同步流程表达异步操作
    本质:

    `Generator`的语法糖
    

    语法:

    async function asyncFun(){
        let result = await Promise.resolve('success');
        console.log(result);//success,如果 Promise.resolve 未传参数则为 undefined
        result = await Promise.reject('fail');
        console.log(result);//Uncaught (in promise) fail
    }
    asyncFun();
    

    特点:

    1. 不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行
    2. 返回的总是Promise对象,可以用then方法进行下一步操作
    3. async取代Generator函数的星号*await取代Generatoryield
    4. 语意上更为明确,使用简单

    相关文章

      网友评论

          本文标题:ES5 6 7常用语法

          本文链接:https://www.haomeiwen.com/subject/wyfimftx.html