原生JavaScript实现对象的混合与克隆效果,带完整版解析代码[helpers.js]

2021-01-28 10:13

阅读:515

标签:style   需求   ima   es5   版本   i++   添加   default   原始类型   

前言:

????????本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小生感激不尽。

????????本篇文章为您分析一下原生JS的混合与克隆

对象混合

页面中如下需求

var obj1 = {
    x: 1,
    y: "a"
}

var obj2 = {
    x: "b",
    o: 6
}


页面上有两个对象
我们要把这两个对象混合成一个
形成如下结构:


// 将obj2混合到obj1中
obj = { 
    x: "b",
    y: "a",
    o: 6
    }


参考代码:


    /**
     *  ES5之前的版本
     * 对象的混合
     * @param {Object} obj1 
     * @param {Object} obj2 
     */
    function mixin(obj1, obj2){
        // 第一步: 创建一个对象
        var newObj = {};
        // 第二步: 循环obj2中的对象
        for(var prop in obj2){
            // 第三步: 将obj2中的属性添加到新创建爱对象中
            newObj[prop] = obj2[prop];
        }
        // 第四步: 循环obj1中的对象
        for(var prop in obj1){
            // 第五步: 看看obj1中的属性在不在obj2中,如果不在就将他加入的新的对象中
            if(!(prop in obj2)){
                newObj[prop] = obj1[prop];
            }
        }
        // 最后返回这个新的对象
        return newObj;
    }


    /**
     * ES6版本
     * 对象的混合
     * @param {Object} obj1 
     * @param {Object} obj2 
     */
    // function mixin(obj1, obj2){
    //     return Object.assgin({},obj1,obj2);
    // }
 
  

在页面中调用


        var obj = mixin(obj1, obj2);
        console.log(obj);

??技术图片

对象克隆

页面中如下需求

        var obj = {
            x: "123",
            y: 456,
            objSon: {
                c: "a"
            }
        }

        var newObj = clone(obj);
        //  要求实现newObj中有obj的所有属性
        //  并且newObj.objSon !== obj.objSon;


下面来看看代码


        function clone(obj) {
            var newObj = {};
            for (var prop in obj) {
                newObj[prop] = obj[prop];
            }
        }


下面来看看效果

技术图片


如果obj是一个数字会怎么样呢?
var obj = 123;

技术图片


为什么会是一个对象呢?
因为我们在function中创建了一个对象
如果obj是一个字符串呢?
var obj = "abcdefg";

技术图片


如果obj是一个数组又会怎么样呢?
var obj = [12,35,65,87,1,3];

技术图片


他克隆出来就是一个伪数组了
并且length属性还得不到

图片


鉴于上面出现的多种情况
我们刚刚写的代码(只是假设他是普通对象,还不是数组对象,数组本身也是对象嘛)就不足以完成一个完整的克隆函数
因此,我们要进行判断


        function clone(obj) {
            if (Array.isArray(obj)) {  // 如果他是一个数组
                return obj.slice();    // 复制数组
            } else if (typeof obj === "object") {  // 如果他是一个普通对象
                var newObj = {};       // 定义一个对象
                for (var prop in obj) {  // 循环obj
                    newObj[prop] = obj[prop];  // 添加属性
                }
                return newObj;         // 返回
            } else {                   // 函数、原始类型
                return obj;            // 直接返回
            }
        }



在页面上打印
var newObj1 = clone(obj1);
var newObj2 = clone(obj2);
var newObj3 = clone(obj3);
var newObj4 = clone(obj4);

技术图片


现在来看这个克隆更加优化了
但是并没有完整
如果obj的属性也是一个对象呢?


        var obj = {
            x: "123",
            y: 456,
            subObj: {
                a: "abc"
            }
        }


newObj本身是不等于obj的,因为是克隆嘛,产生了一个新的对象
但是它里面的subObj属性的地址是一样的
如果我们给newObj.subObj.a ==="XXX";赋值了。
他会导致:obj.subObj.a也跟着改变。
所以我们把目前我们写的这种方式叫做 [浅度克隆]
还有一种克隆叫 [深度克隆] 就是要对他属性做深度处理
因此这个函数还需要一个参数来判断他是否需要深度克隆


        function clone(obj, deep) {
            if (Array.isArray(obj)) {  // 如果他是一个数组
                return obj.slice();    // 复制数组
            } else if (typeof obj === "object") {  // 如果他是一个普通对象
                var newObj = {};       // 定义一个对象
                for (var prop in obj) {  // 循环obj
                    if (deep){
                        // 如果是深度克隆的话,我们把这个属性的值再克隆一遍【递归】
                        newObj[prop] = this.clone(obj[prop], deep);
                    }else {
                        newObj[prop] = obj[prop];  // 添加属性
                    }
                }
                return newObj;         // 返回
            } else {                   // 函数、原始类型
                return obj;            // 直接返回 【递归的终止条件】
            }
        }

        // 再传入第二个参数  
        var newObj = clone(obj, true);

技术图片


针对数组如何深度克隆


        function clone(obj, deep) {
            if (Array.isArray(obj)) {  // 如果他是一个数组
            if(deep){  // 深度克隆
                var newArr = [];  //定义一个空数组
                for(var i = 0; i

技术图片


这样就完成了对象的克隆

完整插件代码

对象混合


this.myPlugin.mixin = function (obj1, obj2) {

    return Object.assign({}, obj1, obj2);
    // // 建立一个新对象
    // var newObj = {};
    // // 进行 for in 循环
    // for (var prop in obj2) {
    //     newObj[prop] = obj2[prop];
    // }
    // // 找到obj1中有但是obj2中没有的属性
    // for (var prop in obj1) {
    //     if (!(prop in obj2)) {
    //         newObj[prop] = obj1[prop]
    //     }
    // }
    // return newObj;
}

对象克隆

/**
 * 克隆一个对象
 * @param {Array} obj  对象
 * @param {boolean} deep 是否深度克隆
 */
this.myPlugin.clone = function (obj, deep) {
    if (Array.isArray(obj)) {
        if (deep) {  //深度克隆
            var newArr = [];
            for (var i = 0; i 


结语

整完!!!

原生JavaScript实现对象的混合与克隆效果,带完整版解析代码[helpers.js]

标签:style   需求   ima   es5   版本   i++   添加   default   原始类型   

原文地址:https://www.cnblogs.com/tewutuyo/p/JavaScript_mixin_clone.html


评论


亲,登录后才可以留言!