Structure-study-es6(深拷贝、Proxy)

1,046 阅读2分钟

var let const

  • var 声明的变量默认在全局上,而let、const声明的变量是在浏览器的script里面

  • 用var 声明的变量会导致变量提升 var function import 。let存在暂时性死区
  • let 不可以重复声明同一个变量
  • const 声明的变量 不可修改(引用类型的里面可以修改)
  • 可以使用 let const来解决异步输出变量的问题
    for (let i = 0; i < 10; i++) {
        setTimeout(()=>{
            console.log(i)   
        });
    };

解构赋值

解构的方式都是根据key来实现。:号重新命名 =用来赋值默认值

    let [,age] = ['姓名','年龄']

    let {name,age:age1,address="xx"} = {name:'xxx',age:10}

展开和合并

    let [,...args] = ['我',10,'北京']

    let {name,...args} = {name:'我',age:12}

深浅拷贝

JSON.stringify 和 Object.assign 都是浅拷贝。并且JSON.stringify 还有一些缺陷

    // 深拷贝 函数

    const deepClone = (value,hash = new WeakMap())=>{
        <!-- 特殊情况判断 -->
        if(value==null) return value;
        if(typeof value !=="object") return value;
        if(value instanceof RegExp) return new RegExp(value)
        if(value instanceof Date) return new Date(value)

        <!-- 拷贝的可能是数组 或者 对象 根据当前属性构造一个新的实例-->

        let instance = new value.constructor();

        if(hash.has(value)){
            // 先去hash中查看一下是否存在过 ,如果存在就把以前拷贝的返回去
            return hash.get(value)
        }
        hash.set(value, instance); // 没放过就放进去
        <!-- 开始拷贝 -->
        for(let key in value){
            instance[key] = deepClone(value[key],hash)
        }

        return instance;
    }

defineProperty (定义getter 和 setter)

    let obj = {}
    let val = ''
    Object.defineProperty(obj,'a',{
        configurable:true, // 是否可删除
        writable:true, // 是否可写
        enumerable:true, // for in 可遍历
        get(){
            return val
        },
        set(value){
            val = value;
        }
    })


    // 应用 vue源码
    function observer(obj){
        if(typeof obj!=="object" || obj == null){
            return;
        }
        for(let key in obj){
            defineReactive(obj,key,obj[key])
        }
    }

    let updateView = () => {
        console.log('更新')
    }

    function defineReactive(obj,key,value){
        // 遍历
        observer(value)

        Object.defineProperty(obj,key,{
            get() {
                return value
            },
            set(val){
                updateView()
                value = val
            }
        })
    }
    observer(obj);
    obj.a.a = 100;
    console.log(obj.a); 

Proxy

兼容性差 支持数组 可以直接更改数组 达到拦截的目的

    let obj = {
        a:{a:2}
    }
    let handler = {
        get(target,key){
            if(typeof target[key] === 'object'){
                return new Proxy(target[key],handler)
            }
            return Reflect.get(target,key)
        },
        set(target,key,value){
            if(key==='length') return true;
            return Reflect.set(target,key,value)
        }
    }

    let proxy = new Proxy(obj,handler);
    proxy.a.a = 100
    console.log(proxy.a.a)