关于vue的几点面试题(vue双向数据绑定和深拷贝浅拷贝之间的区别)

1.vue的双向数据绑定:

  • 实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

  • vue的双向数据绑定整合了整合Observer,Compile和Watcher三者,通过Observer监听数据的变化,通过Compile来编辑解析指令,通过Watcher搭起Observer和Compile的通信桥梁。

2.深拷贝和浅拷贝

浅拷贝:
例如:

let  a=[0,1,2,3,4],
        b=a; 
        console.log(a===b);(true)
         a[0]=1; 
         console.log(a,b);(打印的值一样)

详解:

  • 因为基本数据类型number,string,boolean,null,undefined,symbol
    赋值是存储在栈内存中,当你b=a复制时,栈内存会新开辟一个内存,所以当你此时修改a=2,对b并不会造成影响。这就是深拷贝。

  • 引用数据类型–名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值,当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值,而当我们a[0]=1时进行数组修改时,由于a与b指向的是同一个地址,所以两个数组打印出来的值是一样的,这就是浅拷贝。

  • 这并不是说引用数据类型只能进行浅拷贝。接下来就讲解一下怎样使用深拷贝。这是网上比较流行的一种深拷贝方法,首先进行判断传入的值是否为数组活着对象,然后进行循环遍历判断obj的子元素是否为对象,如果是对象,就进行递归赋值,如果不是,就简单赋值

    function deepClone(obj){
         let objClone = Array.isArray(obj)?[]:{};
         if(obj && typeof obj==="object"){
             for(key in obj){
                 if(obj.hasOwnProperty(key)){
                     //用for...in循环会获取到原型链上的可枚举属性,不过可以使用hasOwnProperty()方法过滤掉。
                     if(obj[key]&&typeof obj[key] ==="object"){
                      //判断ojb子元素是否存在并且是否为为对象,如果是,递归复制
                         objClone[key] = deepClone(obj[key]);
                     }else{
                         //如果不是,简单复制
                         objClone[key] = obj[key];
                     }
                 }
             }
         }
         return objClone;
         }
    

    还有一种比较简单的方法可以进行深拷贝

    利用JSON对象(转化数据格式)的两种方法
    function deepClone(obj){
    let _obj = JSON.stringify(obj),//把JSON对象转化为字符串
    objClone = JSON.parse(_obj);//把JSON字符串转化为对象
    return objClone
    }
    b=deepClone(a);(改变a里面的属性,b不会受影响)

猜你喜欢

转载自blog.csdn.net/liangkaihuaen/article/details/96476912