zoukankan      html  css  js  c++  java
  • 实现 $.extend 的深复制和浅复制

    $.extend 是jquery常用的一个方法,该方法通过传第一个布尔型参数可以指定为深复制还是浅复制,如何使用不在本文讨论。

    先来理解下什么是深复制:

    var ob1 = {

      'name' : 'Jack' ,

      'child' : {

        'name' : 'Tom',

        'age' : '7'

      }

    };

    var ob2 = {

      'name' : 'Rose' ,

      'child' : {

        'name' : 'Mike'

      }

    };

    浅复制后的结果:{'name' : 'Jack' ,'child' : {'name' : 'Mike'}};

    深复制后的结果:{'name' : 'Jack' , 'child' : {'name' : 'Mike', 'age' : '7'}};

    不同之处在于浅复制没有继承ob1.child.age属性,而是直接用ob2.child属性直接进行覆盖了,即只进行了第一层属性的合并,对子元素如果是对象的话,该对象的内部属性不会被继承合并,而会被直接覆盖。

    两种复制各有自身的使用场景。

    那么jquery是怎么实现的呢?大家可以看源码,但是源码看着都头疼!重要的是知道原理然后自己进行实现,先看下浅复制合并,具体思路上代码如下:

        //浅复制
    	function lowerExtend(){
    		var obj1 = arguments[0];//第一个参数
    		var obj2 = arguments[1];//第二个参数
             //判断是否是对象
    		if(typeof(obj1) != 'object' || typeof(obj2) != 'object'){
    			console.warn('Not object');
    			return
    		}
    		//存放结果对象
    		var resObj = {};
    
    		for(var i in obj1){
    			//如果对象2里面有对象1的这个属性则继承过来
    			if(obj2.hasOwnProperty(i)){
    				resObj[i] = obj2[i];
    			}else{
    				resObj[i] = obj1[i];
    			}
    		}
    
    		for(var j in obj2){
    			//上一步已经把obj1和obj2共有的属性全替换为obj2的属性,所以这里只需把obj1里不具有的obj2的属性复制即可
    			if(!obj1.hasOwnProperty(j)){
    				resObj[j] = obj2[j]
    			}
    		}
    		return resObj;
    	}
    

      如果理解了以上浅复制合并的代码,那么深复制起始就是在前复制上加了一层递归调用,整改一下变成以下代码就是深复制:

    //深复制
        function deepExtend(){
            var obj1 = arguments[0];
            var obj2 = arguments[1];
            //存放结果对象
            var resObj = {};
            if(typeof(obj1) != 'object' || typeof(obj2) != 'object'){
                console.warn('Not object');
                return
            }
            //遍历obj1的所有属性
            for(var i in obj1){
                //如果对象2里面有对象1的这个属性则继承过来,否则resObj放obj1[i]
                if(obj2.hasOwnProperty(i)){
                    if(typeof(obj1[i]) == 'object'){
                        //如果obj1[i]是一个对象,那么递归调用这个方法,并把resObj[i]的属性设置为结果
                        resObj[i] = deepExtend(obj1[i],obj2[i])
                    }else{
                        resObj[i] = obj2[i];
                    }
                }else{
                    resObj[i] = obj1[i];
                }
            }
    
            for(var j in obj2){
                //上一步已经把obj1和obj2共有的属性全替换为obj2的属性,所以这里只需把obj1里不具有的obj2的属性复制即可
                if(!obj1.hasOwnProperty(j)){
                    resObj[j] = obj2[j];
                }
            }
            return resObj;
        }

    着色部分为重点不同的地方,jquery源码里其实是通过传入的第一个参数为true和false来这部分代码的是否执行的。

    好了,这篇为本人的第一篇博客,不足之处希望大家不吝赐教,本人定虚心接受。

  • 相关阅读:
    Apache Ant 1.9.1 版发布
    Apache Subversion 1.8.0rc2 发布
    GNU Gatekeeper 3.3 发布,网关守护管理
    Jekyll 1.0 发布,Ruby 的静态网站生成器
    R语言 3.0.1 源码已经提交到 Github
    SymmetricDS 3.4.0 发布,数据同步和复制
    beego 0.6.0 版本发布,Go 应用框架
    Doxygen 1.8.4 发布,文档生成工具
    SunshineCRM 20130518发布,附带更新说明
    Semplice Linux 4 发布,轻量级发行版
  • 原文地址:https://www.cnblogs.com/mdengcc/p/6430039.html
Copyright © 2011-2022 走看看