ECMAScript 2018 对象 rest 和 spread 操作:什么是 Shallow Clone?
ECMAScript 2018 引入了对象 rest 和 spread 操作符,这些操作符使得对象的操作更加便捷和灵活。对象 rest 操作符可以用于将对象的某些属性解构成一个新的对象,而对象 spread 操作符可以用于将一个对象的属性拷贝到另一个对象中。在使用对象 spread 操作符时,我们需要注意一个概念 Shallow Clone(浅拷贝)。
Shallow Clone 是指在使用对象 spread 操作符时,只有第一层属性会被拷贝而深层属性不会被拷贝。这是因为对象 spread 操作符只会将对象的属性进行浅拷贝。如果对象中的属性也是对象或数组,则只会拷贝其引用,而不是其实际值。这意味着如果在源对象和目标对象中修改了某个对象或数组的值,那么它们都会发生变化。
举个例子,对于以下的源对象:
-- -------------------- ---- ------- ----- --------- - - ----- ----- ---- --- -------- - --------- ----- ----- ---- -- -------- ------ ----- -
我们假设我们想使用对象 spread 操作符将其拷贝到一个新的对象 targetObj 中:
const targetObj = { ...sourceObj }
然后我们修改 targetObj 中的深层属性:
targetObj.address.province = '北京' targetObj.hobbies.push('足球')
这时候我们发现 sourceObj 也发生了改变:
console.log(sourceObj.address.province) // 输出 '北京' console.log(sourceObj.hobbies) // 输出 ['游泳', '篮球', '足球']
这是因为拷贝时只拷贝了 address 和 hobbies 的引用,而修改时修改的是地址引用的值,所以 sourceObj 中的属性也发生了改变。
为了避免这种问题,我们可以使用深拷贝来实现拷贝。深拷贝是指把对象和其嵌套的对象属性都拷贝一份,这样就不会出现上面的问题。常见的实现深拷贝的方式有递归拷贝和序列化拷贝。这里我们使用递归拷贝的方式来实现深拷贝:
-- -------------------- ---- ------- -------- -------------- - ----- -------- - ------------------ - -- - --- --- ---- --- -- ---- - -- ------------------------- - ------------- - ------ -------- --- -------- - ------------------- - --------- - - ------ --------- -
使用示例:
-- -------------------- ---- ------- ----- --------- - - ----- ----- ---- --- -------- - --------- ----- ----- ---- -- -------- ------ ----- - ----- --------- - -------------------- -------------------------- - ---- ---------------------------- --------------------------------------- -- -- ---- ------------------------------ -- -- ------ -----
我们发现使用深拷贝后,对 targetObj 的修改不会影响到 sourceObj。在实际开发中,我们应该根据具体情况来决定是否使用深拷贝。
总结:ECMAScript 2018 中的对象 rest 和 spread 操作符使对象操作更加方便和灵活。在使用对象 spread 操作符时,需要注意 Shallow Clone 这一概念。深拷贝可以避免 Shallow Clone 带来的问题,但也会增加程序的复杂度和开销,需要根据实际情况进行取舍。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647d4d7c968c7c53b081c980