首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用vanilla javascript复制JS对象

基础概念

在JavaScript中,对象是引用类型,这意味着当你将一个对象赋值给另一个变量时,实际上是将对象的引用(内存地址)复制给了新变量。因此,如果你直接复制一个对象,修改其中一个变量的属性,另一个变量的属性也会被修改。这就是所谓的“浅拷贝”。

相关优势

  • 深拷贝:能够创建一个完全独立的对象副本,修改副本不会影响原对象。
  • 浅拷贝:在某些情况下,如果你只需要复制对象的第一层属性,浅拷贝会更高效。

类型

  1. 浅拷贝
    • 使用Object.assign()方法。
    • 使用扩展运算符(...)。
  • 深拷贝
    • 使用JSON.parse(JSON.stringify(obj))(有局限性,不能处理函数、循环引用等)。
    • 使用递归函数实现深拷贝。
    • 使用第三方库,如Lodash的_.cloneDeep()方法。

应用场景

  • 浅拷贝:当你需要复制一个对象,并且只修改第一层属性时。
  • 深拷贝:当你需要创建一个完全独立的对象副本,或者对象内部包含嵌套对象时。

示例代码

浅拷贝

代码语言:txt
复制
// 使用Object.assign()
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
shallowCopy.a = 3;
shallowCopy.b.c = 4;
console.log(original); // { a: 1, b: { c: 4 } }
console.log(shallowCopy); // { a: 3, b: { c: 4 } }

// 使用扩展运算符
const shallowCopy2 = { ...original };
shallowCopy2.a = 5;
shallowCopy2.b.c = 6;
console.log(original); // { a: 1, b: { c: 6 } }
console.log(shallowCopy2); // { a: 5, b: { c: 6 } }

深拷贝

代码语言:txt
复制
// 使用JSON.parse(JSON.stringify(obj))
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.a = 7;
deepCopy.b.c = 8;
console.log(original); // { a: 1, b: { c: 2 } }
console.log(deepCopy); // { a: 7, b: { c: 8 } }

// 使用递归函数实现深拷贝
function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) return obj;
  const clone = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;
}

const deepCopy2 = deepClone(original);
deepCopy2.a = 9;
deepCopy2.b.c = 10;
console.log(original); // { a: 1, b: { c: 2 } }
console.log(deepCopy2); // { a: 9, b: { c: 10 } }

遇到的问题及解决方法

问题:使用JSON.parse(JSON.stringify(obj))进行深拷贝时,无法处理函数、循环引用等。

原因JSON.stringify()方法在序列化对象时会忽略函数和undefined,并且会抛出循环引用的错误。

解决方法

  • 使用递归函数实现深拷贝,可以处理函数和循环引用。
  • 使用第三方库,如Lodash的_.cloneDeep()方法。
代码语言:txt
复制
// 使用Lodash的_.cloneDeep()方法
const _ = require('lodash');

const original = { a: 1, b: { c: 2 }, d: function() {} };
const deepCopy3 = _.cloneDeep(original);
deepCopy3.a = 11;
deepCopy3.b.c = 12;
console.log(original); // { a: 1, b: { c: 2 }, d: [Function: d] }
console.log(deepCopy3); // { a: 11, b: { c: 12 }, d: [Function: d] }

参考链接

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Vanilla JS——最轻快的JavaScript框架

简介 Vanilla JS团队维护每个字节的代码框架,每天努力工作,以确保它是小的和直观的。使用Vanilla JS是谁?很高兴你发问!...事实上,Vanilla JS使用量已经远远超过了jQuery, Prototype JS, MooTools, YUI 和 Google Web Toolkit 的总和。...核心功能; DOM(遍历/选择器); 基于原型的对象系统; AJAX; 动画; 事件系统; 正则表达式; 函数作为第一类对象; 闭包; 数学库; 数组库; 字符串库 开始使用 Vanilla JS是世界上最轻量的...javascript 框架,浏览器向站点发送请求前就已经把Vanilla JS加载在浏览器里了。...使用Vanilla JS只需在应用的HTML里加入这行: 当你部署你的应用的时候,使用这个更快的方法: 没错!

6.2K40
  • JavaScriptjs对象进行排序(对象转数组,对象对象

    JavaScriptjs对象进行排序(对象转数组,对象对象)1....详细介绍对象按照key排序对象按照value排序**方法1:象按照key排序** Object.keys(aaa).sort((a,b){ // 代码逻辑,根据keys排序,如果a>b...的排序使用a-b // 这里的a,b就会根据return返回排序,如果a-b返回true就是a大b小,所以a在后b在前 return a-b })如果有更复杂的代码可以使用代码逻辑...,比如这个文章的开头的举例它的key就是字符串2_4 这样的,但是2_8却大于2_16图片这个时候我们就需要使用更复杂的逻辑进行排序,请看如下代码# 方法1:把对象转为数组let aaa = {"2\_...arr = [];for (var sortIndex in aa) { arr.push(aaa[aa[sortIndex]]) }console.log(arr);# 方法2:下面使用数组生成我们想要的排好序的对象

    6.6K40

    javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法

    javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法 前言 在js中,数组和对象复制如果使用=号来进行复制,那只是浅拷贝。...因此,数组以及对象的深拷贝就是javascript的一个基本功了。 评论中有很多人说我误导大家。说这些都是浅拷贝。我不做过深的阐述,本文中涉及到的都是比较浅显的内容。...} = obj obj.old = '22' console.log(obj) console.log(obj2) 运行结果如下: 小结 数组和对象的深拷贝是js中最常见的应用。...更多的数组以及对象的操作方法,可以参考lodash的源码,查看它的源码可以让你的js基础变得非常牢固。我也在学习中。...2017年10月31日补充,使用es6提供的扩展运算符的方法实现深拷贝,简单,高效。并且,对象的深拷贝不会像使用 JSON 方法深拷贝一样,丢失函数等信息,只能用来深拷贝 JSON 数据格式的对象

    3.1K10

    vanilla-tilt.js平滑3D倾斜库的使用

    在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较深入的研究。...文章概要:vanilla-tilt.jsJavascript中一个平滑的3D倾斜库,可以让网页的一些控件变得动态起来,本篇文章主要讲述了如何下载及在网页代码中配置vanilla库。...目录 vanilla库安装 vanilla库配置 案例演示 vanilla库安装          因为网页内设置文件下载不方便,这里将代码放出来,全部复制后,新建一个js文件并且命名为vanilla-tilt.js...库配置 同一目录下.png 将上一步中的vanilla-tilt.js库和要引用的网页文件放置在同一目录下 ---- 在要引用vanilla库的网页文件源代码中进行配置 在源代码最后使用标签导入vanilla库 script标签导入库.png // vanilla-tilt.js

    1.9K30

    js面向对象编程_JavaScript高级编程

    使用对象,指挥对象做事情; ES6中的类和对象 对象JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,如字符串、数值、数组、函数等; 对象是由属性和方法组成的:...,即为对象成员变量赋初始值,它总与new一起使用,他们可把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面; 在JS中,使用构造函数时要注意以下两点: 1、构造函数用于创建某一类对象...,这样就会造成内存浪费; 既然使用同一个对象构建出来的实例对象,那么该函数和属性应该是所有对象所共享的,JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。...对象原型__proto__ 对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto...__proto__对象原型和原型对象prototype是等价的 __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性

    1.1K40

    JavaScript 对象入门使用JSON

    JavaScript对象表示法(JSON)是用于将结构化数据表示为JavaScript对象的标准格式,通常用于在网站上表示和传输数据 什么是 JSON JSON 是一种按照JavaScript对象语法的数据格式...我们已经可以推测出 JSON 对象就是基于 JavaScript 对象,而且这几乎是正确的。...使用 reviver 函数 如果指定了 reviver 函数,则解析出的 JavaScript 值(解析值)会经过一次转换后才将被最终返回(返回值)。...;关于该参数更详细的解释和示例,请参考使用原生的 JSON 对象一文。...使用 JSON.stringify 结合 localStorage 的例子 一些时候,你想存储用户创建的一个对象,并且,即使在浏览器被关闭后仍能恢复该对象

    1.5K10

    JSJavaScript复制内容到剪贴板 代码分享

    引用 直接引用:  包: npm install clipboard --save ,然后 import Clipboard...from 'clipboard'; 使用 从输入框复制 现在页面上有一个  标签,我们需要复制其中的内容,我们可以这样做: <input id="demoInput" value="hello...直接<em>复制</em> 有的时候,我们并不希望从  中<em>复制</em>内容,仅仅是直接从变量中取值。... clipboard ,为了使得生命周期管理更加的优雅,在<em>使用</em>完之后记得 btn.destroy() 销毁一下。...clipboard <em>使用</em>起来是不是很简单。但是,就为了一个 copy 功能就<em>使用</em>额外的第三方库是不是不够优雅,这时候该怎么办?那就用原生方法实现呗。

    2.9K30

    JavaScriptJS面向对象的模式与实践

    参考书籍 《JavaScript高级语言程序设计》—— Nicholas C.Zakas 《你不知道的JavaScript》  —— KYLE SIMPSON 在JS的面向对象编程中,我们最为关注的是两种行为...所以,JavaScript中的“原型”当然不是一个普通的对象,它是prototype对象以及背后的一系列机制形成的一个“整体”!...1到4点都告诉我们:"哎呀protoType在JS面向对象里是多好的一个东西啊!...返回name的值“XXX” 仅仅使用原型链实现继承的缺点 仅使用原型链实现继承的缺点,和原型模式创建对象的缺点一样: 1. 你无法向父类构造函数中传递参数 2....而原型,就是一个来自于OLOO的世界而进入OO的世界的人物 对原型恰当的认知方式 原型一直以来难以让人理解的原因是, 我们竭尽全力想要把它纳入JS面向对象设计的一部分,但是又不得不面对它在使用中诸多不满足面向对象要求的表现

    1.1K60

    重学jsJavaScript 面向对象的程序设计(创建对象

    5.2 原型与in操作符 有两种方式使用 in 操作符:单独使用和在 for-in循环中使用。在单独使用时,in操作符会在通过对象能够访问给定属性时返回 true,无论该属性存在于实例中还是原型中。...*注意:* 使用动态原型模式时,不能使用对象字面量重写原型,如果在已经创建了实例的情况下重写原型,那么就会切断现有实例与新原型之间的联系。 8....本文章为《重学js系列》的第六章上半部分,后续还为大家带来js基础的更多文章。...重学JS系列: 1、重学jsJavaScript简介 2、重学js之在HTML中使用JavaScript 3、重学jsJavaScript基本概念(上)- 数据类型 4、重学jsJavaScript...基本概念(中)- 操作符 5、重学jsJavaScript基本概念(下)- 运算符 6、重学jsJavaScript变量、作用域和内存问题 7、重学jsJavaScript引用类型

    1.5K30

    【如果你要学JS 】——JavaScript-内置对象

    1.内置对象JavaScript中的对象分为3种:自定义对象,内置对象,浏览器对象。...前面两种对象JS基础内容,属于ECMAScript;第三个浏览器对象属于我们JS独有的,我们JSAPI讲解 内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能...(属性和方法)内置对象最大的优点就是帮助我们快速开发 JavaScript提供了多个内置对象: Math、Date 、Array、 string等2.什么是MDN学习一个内置对象使用,只要学会其常用成员的使用即可...3.如何使用对象中的方法1.查阅该方法的功能2.查看里面参数的意义和类型 ,返回值的意义和类型3.通过demo进行测试1,输入想要搜索的内容 2,点击这里可以换成中文的4.Math是啥?...Math数学对象不是一个构造函数,所以不需要new来调用而是直接使用里面的属性和方法即可5.封装对象 var myMath = { PI: 3.14159265358979

    24200

    深入理解javascript中的继承机制(3)属性复制对象之间的继承深复制原型继承原型继承与属性复制的混合使用

    我们开始换一种思路实现继承,可不可以直接将父对象的属性直接复制给子对象,这样子对象不久也拥有了父对象的属性,相当于继承。...同时我们还要切记一点,我们实现的是浅复制,也就是直接复制的值,这样的话: ** 只有对于那些由原始数据类型构成的属性,才会被重复,那些对象的引用,只会复制引用,指向的还是同一个对象 ** 下面我们使用上面实现的...深复制 前面介绍的复制的方法都是浅复制,也就是只对于原始数据类型的属性会复制出副本,而对于引用类型的对象则只是复制出引用。这样造成的问题就是,当操作新对象时,可能会无意识的覆盖改变旧对象。...原型继承与属性复制的混合使用 我们知道实现继承就是将已有的功能归为所有,我们在new一个新对象的时候,应该继承于现有对象,然后再为其添加额外的属性与方法。...,一个用于原型继承,一个用于属性拷贝,这里使用的是浅拷贝,也可以改成深拷贝。

    1.5K20
    领券