JS随笔:关于原始值和引用值的浅层克隆和深层克隆

    技术2026-08-04  26

    JS随笔:关于原始值和引用值的浅层克隆和深层克隆

    在学习的过程中写这篇文章,总结一些学习克隆要点

    在进行克隆的环节前要了解什么是原始值和引用值 在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值。以下是W3C的定义 1.原始值:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。 有五个值:Undefined,Null,Boolean,Number,String 2.引用值:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。 包括 Object(Array也是Object)、Function、Date、RegExp。

    克隆的过程 1.遍历你所要克隆的对象/数组:for(var prop in obj) / for(var prop in arr) ps:数组是一个特殊的对象,因此for in 循环通吃数组和对象

    2.判断是不是原始值 typeof() ,返回是object基本是引用值,除了null,其他是原始值

    3.判断是数组还是对象 识别一个变量里面传的的数组还是对象有三种方法 (1).constructor (2).instanceof (3).toString()方法

    4.重新建立一个空的,相应的数组或对象

    5.递归(递归核心思想:(1)找规律 (2)找出口)

    浅层克隆:针对克隆的值是原始值,没有引用值时才能使用的。

    因为原始值存储在栈中。意思就是说,当一个原始变量把值赋给另一个原始变量时,只是把栈中的内容复制给另一个原始变量,此时这两个变量互不影响,即当一个变量值改变时,另一个变量不会因此而发生任何变化。

    简单来说:就是克隆了另外一个仓库,有两个仓库,互不影响,但这是克隆对象只有原始值的情况下

    例子:

    var obj = { name :'wzy', sex:'male', age:24 } var obj1 = {}; function clone(origin,target){ var target = target || {}; for(var prop in origin){ target[prop] = origin[prop] } return target; } clone(obj,obj1);

    这个例子obj的值全部是原始值,因此直接遍历对象然后克隆

    深层克隆:无论是原始值还是引用值都互不影响

    当克隆的对象包含引用值时,这时候改变克隆的值,被克隆的对象也会改变。

    因为引用值于原始值不同,引用值把引用变量存储在栈中,而实际的对象存储在堆中。每一个引用变量都有一根指针指向其堆中的实际对象。当变量改变时,另一个变量也会改变.因此要用深度克隆

    简单来说:引用值其实提供一个仓库的地址,你改变了这个仓库的东西,那么你克隆的对象会因为这个仓库改变而改变,因此深度克隆很有必要 例子:

    var obj = { name :'wzy', sex:'male', age:24, card:[5,'zy'], dasd:{ a:888, d:'gg' } } var obj1 = {} function deepClone(origin,target){ var target = target || {}, toStr = Object.prototype.toString, arrStr = '[object Array]'; for(var prop in origin){ if(origin.hasOwnProperty(prop)){ if (origin[prop] !== 'null' &&typeof(origin[prop]) == 'object'){ // if(toStr.call(origin[prop])==arrStr){ // target[prop]=[]; // }else{ // target[prop]={}; // } // 用三目运算符可以简洁代码判断 target[prop]=(toStr.call(origin[prop])==arrStr)? [] :{}; deepClone(origin[prop],target[prop]); }else{ target[prop] = origin[prop]; } } } return target; }

    ps:(在后台验证时…)对象{}是不能直接.push方法的,要在对象里手动添加。数组[ ]倒是可以直接用.push方法

    上面的例子中,obj有对象和数组,但是用了深度克隆就不会互相影响了

    总结: 克隆前来要判断, 原始引用要区分。 克隆好来五步走, 一步不缺无BUG。

    Processed: 0.014, SQL: 9