Wisdom a Web Developer

工作中常用的ES6 ES7 ES8

2018-07-03
wisdom

前端技术日新月异,这一两年ES6, ES7, ES8快速普及, 的确给我我们的开发工作带来了很大的便利,以下介绍一下我自己在工作中常用到的ES新语法

(一) ES6 语法:

let const

块级作用域

没有变量提升, 并且块级作用域(封闭作用域)

    if (true) {
        console.log(a) // 报错 : Uncaught ReferenceError: a is not defined(…)
        let a = 'js'
    }
    // 这里也访问不到 a

一个作用域不能重复声明同一个值

    if(true){
        var a = 1;
        if (true) {
            let a = 'js' // a == 'js'
        }
        a = 3; // a == 3;
        let a = 2 ; // 报错Uncaught SyntaxError: Identifier 'a' has already been declared ;

        // 题外话, 在console中, 产生报错后a的内存指引被清除, 可以重新赋值
        let a = 0; // a == 0
        // 但实际开发中, 产生报错, 后面的代码不再执行, 所以不会有这种情况产生
    }
const 不能被重新赋值

const声明一个只读的常量。一旦声明,常量的值就不能改变。

    const a = 1;
    a = 2; // 报错 : Uncaught TypeError: Assignment to constant variable.(…)

const声明的数组, 对象, 还可以进行增改查, 但是不能重新定义

    const a = [];
        a.push(2)   // a == [2]

    const b = {};
        b.a = a ;   // 包含了a数组的对象

只在声明的作用域有效(与let一样)

    if(true){
        const c = 1;
    }
    // 此处访问会报错:   Uncaught ReferenceError: c is not defined(…)

箭头函数

我们经常要给回调函数给一个父级的this

常用办法就是 var self = this 定义一个变量接住他

使用 箭头函数,this 将不会受到影响,可以直接用this调用父级的this

判断字符串

includes()

返回布尔值,表示是否找到了参数字符串。

    str.includes(searchString[, position])

searchString

要在此字符串中搜索的字符串

position

可选。从当前字符串的哪个索引位置开始搜寻子字符串;默认值为0。

    'Blue Whale'.includes('blue'); // return false
    'Blue Whale'.includes('Whale' , 2); // return true
startsWith()

返回布尔值,表示参数字符串是否在源字符串的头部。

    'Blue Whale'.startsWith('blue'); // return false
    'Blue Whale'.startsWith('Whale' , 2); // return false
    'Blue Whale'.startsWith('Whale' , 5); // return true
endsWith()

返回布尔值,表示参数字符串是否在源字符串的尾部。

    'Blue Whale'.endsWith('blue'); // return false
    'Blue Whale'.endsWith('Whale' , 10); // return true
    '0Blue'.endsWith('Blue' , 5); // return true

模板字符串

    const name = 'Tiger';
    const age = 13;
    console.log(`My cat is named ${name} and is ${age} years old.`);
    // My cat is named Tiger and is 13 years old.

解构

解构数组
    let [a, b, c, d] = [1, 2, 3, 4];
    console.log(a); //1
    console.log(b); //2
解构对象
    let luke = { occupation: 'jedi', father: 'anakin' };
    let {occupation, father} = luke;
    console.log(occupation); // jedi
    console.log(father); // anakin

模块

导出
    function sumThree(a, b, c) {
        return a + b + c;
        }
    export { sumThree };
引入
    import { sumThree } from 'math/addition';

默认参数

    function addTwoNumbers(x=0, y=0) {
        return x + y;
    }

    addTwoNumbers() // 0

剩余参数

    function(a, b, ...restArgs) {
      // ...restArgs 即为剩余参数, 是一个Array对象
    }

剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。

arguments 对象不是一个真实的数组,而剩余参数是真实的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach,pop。

arguments 对象对象还有一些附加的属性 (比如callee属性)。

    function fun1(...theArgs) {
      alert(theArgs.length);
    }

    fun1();  // 弹出 "0", 因为theArgs没有元素
    fun1(5); // 弹出 "1", 因为theArgs只有一个元素
    fun1(5, 6, 7); // 弹出 "3", 因为theArgs有三个元素

Object.keys(object)

    var obj = {'a': 'Beijing', 'b': 'Haidian'};
    console.log(Object.keys(obj));    //['a', 'b']

Object.assign()

    // target目标对象。
    // sources(多个)源对象。
    Object.assign(target, ...sources)

实例:

    var obj = { a: 1 };
    var copy = Object.assign({}, obj); // {a: 1}
  • 继承属性和不可枚举属性是不能拷贝的

  • 原始类型会被包装为 object

异常会打断接下来的拷贝任务

    var v1 = "abc";
    var v2 = true;
    var v3 = 10;
    var v4 = Symbol("foo")

    var obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
    // 原始类型会被包装,null 和 undefined 会被忽略。
    // 注意,只有字符串的包装对象才可能有自身可枚举属性。
    console.log(obj); // { "0": "a", "1": "b", "2": "c" }

展开操作

    Math.max(...[-1, 100, 9001, -32]);
    let cities = ['San Francisco', 'Los Angeles'];
    let places = ['Miami', ...cities, 'Chicago']; // ['Miami', 'San Francisco', 'Los Angeles', 'Chicago']

    // 声明一个类名为 Rectangle  的JS类
    // constructor方法用于创建和初始化使用一个类创建的一个对象。只允许存在一个
    class Rectangle {
        constructor(height, width) {
            this.height = height;
            this.width = width;
        }
    }

如果没有指定this, this值将为undefined。this可以在constructor里声明

    class Animal {
        speak() {
            return this;
        }
        static eat() {
            return this;
        }
    }

    let obj = new Animal();
    let speak = obj.speak;
    speak(); // undefined

    let eat = Animal.eat;
    eat(); // undefined
static

static方法可以不用实例化直接调用

    class Animal {
        static eat() {
            console.log('eat');
        }
    }

    let eat = Animal.eat
    eat(); // eat
类的get 与 set
    // 创建一个 Chef 类
    class Chef {
        // 初始化
        // 接收参数
        constructor(food){
            this.food = food;
            this.dishs = [];
        }

        get menu(){
            return this.dishs;
        }

        set menu(dishs){
            this.dishs.push(dish)
        }

        cook(){
            console.log(this.food)
        }

    }
    let qing = new Chef()
    console.log(qing.menu = "?") //?
    console.log(qing.menu = "") // ❦
类的继承extends
    class Person{
        constructor(name, birthday){
            this.name = name
            this.birthday = birthday
        }

        intro(){
            return `${this.name}, ${this.birthday}`
        }
    }

    // 使得Chef类 继承 Person类
    class Chef extends Person{
        constructor(name, birthday){
            // 调用父类的constructor函数
            super(name, birthday)
        }
    }

    let qing = new Chef('qing', "1949-10-1");

    // 实例化后才可使用 Chef类 的intro方法
    qing.intro() // "qing, 1949-10-1"

Set对象

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

个人主要用于去重

    //定义两个数组
	var array = [1, 2, 1, 1, '1', ''];
	var array1 = [1, '', 2, '', 3, 4, '5', '1', '6'];
	//构建带array,array1两个参数的函数
	function uq(array, array1) {
		//将array数组转换成set对象
		setObj = new Set(array)
		//循环数组array1,并将值通过add插入set对象中,此时重复数据并不会插入其中
		for(i = 0; i < array1.length; i++) {
			setObj.add(array1[i]);
		}
		//使用Array.from()方法将set对象转换成数组,并使用sort()方法排序
		return Array.from(setObj).sort();
	}

	//查看输出结果
	console.log(uq(array, array1)); // [1, "1", 2, 3, 4, "5", "6", "一", "二"]

Map对象

可以理解成键值对

    let map = new Map();

    map.set('name', 'david');

    map.get('name');

    map.has('name');
Map 结构转为数组结构

比较快速的方法是结合使用扩展运算符(…)

    let map = new Map([
     [1, 'one'],
     [2, 'two'],
     [3, 'three'],
    ]);
    [...map.keys()]
    // [1, 2, 3]
    [...map.values()]
    // ['one', 'two', 'three']
    [...map.entries()]
    // [[1,'one'], [2, 'two'], [3, 'three']]
    [...map]
    // [[1,'one'], [2, 'two'], [3, 'three']]
Map 循环遍历

keys():返回键名的遍历器。 values():返回键值的遍历器。 entries():返回所有成员的遍历器

    let map = new Map([
     ['F', 'no'],
     ['T', 'yes'],
    ]);

    for (let key of map.keys()) {
        console.log(key);
    }
    // "F"
    // "T"

    for (let value of map.values()) {
        console.log(value);
    }
    // "no"
    // "yes"

    for (let item of map.entries()) {
        console.log(item[0], item[1]);
    }
    // "F" "no"
    // "T" "yes"

    // 或者
    for (let [key, value] of map.entries()) {
        console.log(key, value);
    }

    // 等同于使用map.entries()
    for (let [key, value] of map) {
        console.log(key, value);
    }
Map 获取长度
    map.size;
Map 获取第一个元素
    const m = new Map();
    m.set('key1', {})
    m.set('keyN', {})

    console.log(m.entries().next().value); // [ 'key1', {} ]

Promises

远离回调地狱,可以转换成垂直代码(神器啊 不了解的同学一定要去看看)

    const promist = new Promise(function(resolve,reject){
        if(/*异步操作成功*/){
            resolve(value);
        }else{
            reject(error);
        }
    })

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

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

详细可看Promise - 廖雪峰的官方网站

Generators

用同步的代码风格来写异步代码

    function* genFunc() {

        // (A)

        console.log('First');

        yield; //(B)

        console.log('Second'); //(C)

    }

(二) ES7 语法

数组实例的 includes()

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。该方法属于 ES7 ,但 Babel 转码器已经支持。

    [1, 2, 3].includes(2); // true
    [1, 2, 3].includes(4); // false
    [1, 2, NaN].includes(NaN); // true

该方法的第二个参数表示搜索的起始位置,默认为 0 。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为 -4 ,但数组长度为 3 ),则会重置为从 0 开始。

    [1, 2, 3].includes(3, 3); // false
    [1, 2, 3].includes(3, -1); // true

(2) 求幂运算

    2**3 == 8

(三) ES8 语法

object.entries()

    let obj = {a: 1, b: 2, c: 3};

    Object.entries(obj).forEach(([key, value]) =>{
        console.log(key + ": " + value); // 输出a: 1, b: 2, c: 3
    })

    // 有木有感觉和ES6的Map 对象很像

Async Await

异步看起来和同步写法一样

    async fetchData(query) =>{
        try {
            const response = await axios.get(`/q?query=${query}`);
            const data = response.data;
            return data;
        }
        catch (error) {
            console.log(error)
        }
    }

    fetchData(query).then(data => {
        this.props.processfetchedData(data)
    })

Similar Posts

Comments

隐藏