ES6要素概览-结构心中留

74 阅读4分钟

你不知道的Javascript-下 ES6

》》语法

块级作用域

let、const解决问题 变量提升(旧版解决变量提升,使用立即执行函数)

    const(值类型,对象类型)
            没有深度只读,需要遍历设置Object.freeze()
            手写,需进行类型判断和递归

展开、收集运算符...

    展开数组:拼合数组 let arr = [...arr1, ...arr2, ...arr3]
    收集数组-函数参数收集:收集多余参数至数组 function testFunc(a, b, c, ...d){ console.log(d.length) }
    展开对象:合并对象 let obj = {...obj1, ...obj2}
    收集对象:let {aaa, ...ccc} = {a: 100, b: 'gpf', c: 123}   ccc:{b: 'gpf', c: 123}
默认值参数
	函数默认值(替代原有写法 let yy = params1 || 'initData'),解构输出值的默认值

解构-简洁赋值(可设置默认值,用于构造数据)

    数组解构(对位) let [a, b=1222, c, d=100]=[1,2,3]   =====> 1 2 3 100
    对象解构(相同key对应)---支持深层嵌套和取重复的键(下文的o2.x和yyy都可取到a的值)
    另外的活用:
            var o1 = { a: 1, b: 2, c: 3 }, 
             o2 = {}; 
            ( { a: o2.x, b: o2.y, c: o2.z, a: yyy } = o1 ); 
    解构注意事项:(解构可能污染作用域,另外解构的数据是浅拷贝,会互相影响)

对象字面量扩展

    属性(键值一样可缩写)
    方法可省略functiongetData(){})

模版字面量``(可插值和解析表达式)

箭头函数

    特征:改变this指向,父级作用域;简洁。
    典型不适用场景:
    dom1.addEventListener('resize', ()=>{
            // 此时this指向的不是预期的监听dom对象,而是全局对象
    })
    let obj = {name: 'gpf', getName()=>{}}
    obj.getName() this取得的是外部对象,而不是对象实例本身
    箭头函数不能取到参数列表:arguments

》》代码组织

迭代器(一个用于消耗的数据结构,借助迭代器接口) 迭代器操作对象:数组(js中的nodeList--数据结构)、set/map集合(类数组对象)、字符串(对象类型不行) 自定义迭代器:实现其[Symbol.iterator]接口

    // 一、小例-数组转为迭代器
    var arr = [1,2,3]; 
    var it = arr[Symbol.iterator](); 
    it.next();
    
    // 二、样例-自定义迭代器(斐波那契数列)
    var Fib = { 
     [Symbol.iterator]() { 
     var n1 = 1, n2 = 1; 
     return { 
     // 使迭代器成为iterable 
     [Symbol.iterator]() { return this; }, 
     next() { 
     var current = n2; 
     n2 = n1; 
     n1 = n1 + current; 
     return { value: current, done: false }; 
     }, 
     return(v) { 
     console.log( 
     "Fibonacci sequence abandoned." 
     ); 
     return { value: v, done: true }; 
     } 
     }; 
     } 
    }; 
    for (var v of Fib) { 
     console.log( v ); 
     if (v > 50) break; 
    }

    // 三、流控-迭代器的流控
    var tasks = { 
            [Symbol.iterator]() { 
                    var steps = this.actions.slice(); 
                    return { 
                            // 使迭代器成为iterable 
                            [Symbol.iterator]() { return this; }, 
                            next(...args) { 
                                    if (steps.length > 0) { 
                                            let res = steps.shift()( ...args ); 
                                            return { value: res, done: false }; 
                                    } 
                                    else { 
                                            return { done: true } 
                                    } 
                            }, 
                            return(v) { 
                                    steps.length = 0; 
                                    return { value: v, done: true }; 
                            } 
                    }; 
            }, 
            actions: [] 
    };

    tasks.actions.push( 
     function step1(x){ 
     console.log( "step 1:", x ); 
     return x * 2; 
     }, 
     function step2(x,y){ 
     console.log( "step 2:", x, y ); 
     return x + (y * 2); 
     }, 
     function step3(x,y,z){ 
     console.log( "step 3:", x, y, z ); 
     return (x * y) + z;
     }
     )

    var it = tasks[Symbol.iterator](); 
    it.next( 10 ); // step 1: 10 
     // { value: 20, done: false } 
    it.next( 20, 50 ); // step 2: 20 50 
     // { value: 120, done: false } 
    it.next( 20, 50, 120 ); // step 3: 20 50 120 
     // { value: 1120, done: false } 
    it.next(); // { done: true }
    
    

生成器(用于阻塞流控)

    function *gen(){
            console.log('生成器 函数')
            yield console.log(1)
            yield console.log(2)
            yield console.log(3)
            return console.log(4)
    }

    斐波那契数列的生成器函数
    function* fibs() {
      let a = 0;
      let b = 1;
      while (true) {
            yield a;
            [a, b] = [b, a + b];
      }
    }
    let [first, second, third, fourth, fifth, sixth,a,b,c,d,e] = fibs();
    可以方便的解构:a = 8;d= 34
    

模块(esm)

import {api1, api2} from './js.js' 按需导入导出

类(扩展基础类的功能extend:class MyCoolArray extends Array , Error 扩展数组、扩展错误基类)

异步流控

promise(为异步操作提供稳定性、有序性、可预测性)
promise+生成器(完成流控) 有点类似async、await

集合

set、map(注意操作api的不同)

新增api

Array
初始化转化类
	from类数组转化为数组
	of创建空数组
	falt按层级扁平化多维数组
查询遍历类
	indexOf(严格匹配,返回下标)类比find(自定义匹配方法,返回匹配元素),findIndex则可完全代替indexOf
	也类似some 但这种方式的缺点是如果找到匹配的值的时候,只能得到匹配的 true/false 指示,而无法得到真正的匹配值本身。
	filter(匹配的数组组织返回)
            map、reduce
            someevery《《《 foreach(不能中断return循环)
Object,
Number

元编程

Proxy(返回一个Proxy对象包裹的响应式对象,是Object.defineProperty的升级版,恰恰可以用于vue3的响应式)

    let person = {name: 'gpf', age: 100}
    const p = new Proxy(person, {
            get(obj, property){
                    // 无明确指定属性
                    console.log('get property: '+ property)
                    return obj.property
            },
            // 修改或者新增属性
            set(obj, property, val){
                    if (property === 'age') {
                            if (!Number.isInteger(val)) {
                                    throw new TypeError('The age is not an integer');
                            }
                            if (val > 200) {
                                    throw new RangeError('The age seems invalid');
                            }
                    }
                    // 属性值修改,进行页面更新渲染操作
                    obj[property] = val
                    console.log('修改了obj对象的property属性,修改值为val')
            },
            deleteProperty(target, propName){
                    console.log('删除属性需要,自己去实现下,相当于封装了自己的元操作')
                    return delete target[propName]
            }
    })
    console.log(p)
    p.name // 进行get逻辑,因为p成为Proxy代理对象
    person.name // 不进行操作get逻辑

Reflect

ES6展望