关闭

简单实现在Js中克隆对象

时间: 2020-03-25阅读: 453标签: 对象

JavaScript 的原始数据类型(例如number、string、null,undefined 和 boolean)是不可变的,这意味着一旦创建,它们的值就无法更改。但是对象和数组是可变的,允许在创建后修改其值。实际上,这意味着基元是通过值传递的,而对象和数组是通过引用传递的。考虑以下例子:

let str = 'Hello';
let copy = str;
copy = 'Hi';
// str = 'Hello', copy = 'Hi'

let obj = { a: 1, b: 2 };
let objCopy = obj;
objCopy.b = 4;
// obj = { a: 1, b: 4}, objCopy = { a: 1, b: 4 }

在 obj 中发生的事是该对象是通过引用传递给 objCopy 的,因此修改其中一个变量的值也会影响另一个变量。 objCopy 实际上是引用同一对象的别名。我们可以使用多种技术(例如,展开运算符(...)或带有空对象的 Object.assign())来克隆对象,以解决此问题:

let obj = { a: 1, b: 2};
let clone = { ...obj };
clone.b = 4;
// obj = { a: 1, b: 2}, clone = { a: 1, b: 4 }

let otherClone = Object.assign({}, obj);
otherClone.b = 6;
clone.b = 4;
// obj = { a: 1, b: 2}, otherClone = { a: 1, b: 6 }

这两种解决方案都展示了浅克隆的例子,因为它们适用于外部(浅)对象,但是如果我们嵌套(深)对象,这些对象最终将通过引用传递,从而导致失败。有几种方法可以解决这个问题,其中更简单的方法是用 jsON.stringify() 和 jsON.parse() 处理:

let obj = { a: 1, b: { c: 2 } };
let clone = JSON.parseJSON.stringify(obj));
clone.b.c = 4;
// obj = { a: 1, b: { c: 2 }}, clone = { a: 1, b: { c: 4 } }

虽然上面的例子有效,但它必须序列化和反序列化整个对象,这可能会严重影响代码的性能,所以它可能不适用于较大的对象或对性能要求很高的项目。

另外,你可以用递归来深度克隆对象,并且速度要快得多,例如下面代码中的递归函数。同样,如果你想使用现成的浅克隆函数,则可以这样做:const shallowClone = obj => Object.assign({}, obj);。

const deepClone = obj => {
  if (obj === null) return null;
  let clone = Object.assign({}, obj);
  Object.keys(clone).forEach(
    key => (clone[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
  );
  return Array.isArray(obj) && obj.length
    ? (clone.length = obj.length) && Array.from(clone)
    : Array.isArray(obj)
      ? Array.from(obj)
      : clone;
};
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/8714

关闭

Js中Blob是什么?

MDN给出的解释:Blob 对象表示一个不可变、原始数据的类文件对象;创建一个blob只有两种方式1、通过new Blob();使用blob.slice切割,创建一个新的blob对象;读取blob唯一方式,使用fileReader

js获取object对象的长度

我们都知道必须是具体数据类型才有长度,所以size和length都无法测量object对象的长度,那么如何计算对象的长度,即获取对象属性的个数呢?

js包装对象

对象是 JavaScript 语言最主要的数据类型,三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的包装对象。所谓包装对象,就是分别与数值、字符串、布尔值相对应的Number、String、Boolean三个原生对象。

JavaScript arguments 对象详解

arguments 是一个类数组对象。代表传给一个function的参数列表。乍一看,结果是个数组,但并不是真正的数组,所以说 arguments 是一个类数组的对象(想了解真正数组与类数组对象的区别可以一直翻到最后)。

js对象 对属性调用.和[] 两种方式的区别

在 JS 对象中,调用属性一般有两种方法——点和中括号的方法。 标准格式是对象.属性(不带双引号),注意一点的是:js对象的属性,key标准是不用加引号的,加也可以,特别的情况必须加,如果key数字啊,表达式啊等等

vue事件获取当前对象

currentTarget:返回其监听器触发事件的节点,就是你的点击事件绑定在哪一个元素上 ,arget:返回事件的目标节点(触发该事件的节点),就是你当前点击的是哪一个元素

JS 的 Document对象

Document 对象是是window对象的一个属性,因此可以将document对象作为一个全局对象来访问。当浏览器载入 HTML 文档, 它就会成为 Document 对象。Document对象的 属性和方法

js中new的本质

用 var anObject = new aFunction() 形式创建对象的过程实际上可以分为三步: 第一步是建立一个新对象; 第二步将该对象内置的原型对象设置为构造函数prototype引用的那个原型对象; 第三步就是将该对象作为this参数调用构造函数,完成成员设置等初始化工作。

使用Js的Proxy监听对象属性变化并进行类public/private的访问控制

Proxy是ES6的引入的一个对象监听机制。可视为JavaScript对象的一个代理中间件。用户在访问对象时,会触发自定义行为。Proxy最简单的用法是可以监听对象属性的变化

node中的全局对象是什么?

JavaScript中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。那么在node中全局对象是什么?在浏览器JavaScript中,通常window是全局对象, 而Node.js中的全局对象是globa,所有全局变量(除了 global 本身以外)都是global对象的属性。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!