首先,我们还是举个例子来说明对象赋值操作的问题吧:

ps: 本文默认约定log = console.log

 function A(){}
A.prototype.x = 10;
var a1 = new A();
A.prototype = {
x: 20,
y: 20
};
var a2 = new A();
log([a1.x, a1.y, a2.x, a2.y]); // [10, undefined, 20, 20]

js中对象赋值操作我们可以通过c语言中得指针概念来解释。

对象的浅拷贝

直接通过赋值操作符“=”将变量a中的对象赋值给变量b,此时我们更改a、b其中一个,另一个也会随之更改。

var a = [1, 1],
b = a;
b[0] = 2;
log(a[0]); // 2

因为我们在将a的对象赋值给b时,js引擎内部的操作只是简单的将a所指的对象的地址赋值给b,此时a与b指向内存中同一个对象,所以才会出现这种情况。这种赋值方式称为对象的浅拷贝。

我们可以从另一个方面论证我们的观点:

log(a === b); // true,毫无疑问

var c = [2, 1];
log(a === c); // false

出现这种情况的原因就是变量c指向的是另一个和变量a指向的对象的值相同的对象,仅仅只是两个指向的对象的值相同,但两个对象在内存的地址是不一样的,所以是false。

另外,我们知道js数组中有一些方法可以实现数组的完全复制,即两个变量分别指向两个对象:

	b = a.concat([]),
c = a.slice(0),
d = a.splice(0, a.length);
log(b === a); // false

但是我们要针对对象进行复制的话,只能手动进行模拟,即所谓的对象深拷贝。

对象的深拷贝

顾名思义,就是利用“=”对于基本类型的操作不存在上述问题,通过for-in深度遍历对象的属性,然后将其赋值给另一个新的对象。

function cloneObj(obj) {
var tempObj = {}; if (obj instanceof Array) {
tempObj = [];
} for (var prop in obj) {
if (typeof prop === 'Object') {
cloneObj(prop);
} tempObj[prop] = obj[prop];
} return tempObj;
} var myCountry = {
name: 'China',
birth: 1949
}, country = cloneObj(myCountry); log(country === myCountry); // false

结束语

最后,我们回到第一个例子,会发现,引擎内部对于new对象的原型链也是通过简单的赋值操作的方式,即对象的浅拷贝。而ES5新增的Object.create()也是浅拷贝的一种封装:

var myCountry = {
name: 'China',
birth: 1949
}, country = Object.create(myCountry); console.log(country.__proto__ === myCountry); // true

Javascript对象赋值操作的更多相关文章

  1. C风格字符串和C++ string 对象赋值操作的性能比较

    <<C++ Primer>> 第四版 Exercise Section 4.3.1 部分Exercise 4.2.9 习题如下: 在自己本机执行如下程序,记录程序执行时间: # ...

  2. javascript数组赋值操作的坑

    描述:数组对象赋值,即arr1=[{},{},{}]这种数据结构的对象赋值,将arr1赋值给arr2:然后删除arr2里的元素 一.最常用的= arr2 = arr1; detect(val) { l ...

  3. javascript数组赋值操作

    最近在司徒正美的<javascript框架设计>,在里面发现了一个段代码 ...... var _len = arr1.length; while (_len) { arr2[--_len ...

  4. JavaScript对象属性赋值操作的逻辑

    对象进行属性赋值操作时,其执行逻辑如下所示: 1. 当前对象中是否有该属性?有,进行赋值操作:没有,进行下一步判断. 2. 对象的原型链中是否有该属性?没有,在当前对象上创建该属性,并赋值:有,进行下 ...

  5. 深入理解javascript对象系列第二篇——属性操作

    × 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...

  6. javascript:面向对象和常见内置对象及操作

    本文内容: 面向对象 常见内置对象及操作 首发日期:2018-05-11 面向对象: JavaScript 是面向对象的编程语言 (OOP).OOP 语言使我们有能力定义自己的对象和变量类型. 对象是 ...

  7. jquery实现点击展开列表同时隐藏其他列表 js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象

    这篇文章主要介绍了jquery实现点击展开列表同时隐藏其他列表的方法,涉及jquery鼠标事件及节点的遍历与属性操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了jquery实现点击 ...

  8. JavaScript 对象的创建和操作

    <script>         // 对象是属性的无序集合,每个属性都是一个名/值对. 属性名称是一个字符串.         // 对象种类         // 内置对象(nativ ...

  9. Javascript对象的方法赋值

    Javascript对象编程学习中,一直不能很好的掌握对象的属性(property)和方法(method).今天在写代码过程中,又犯了一个低级错误. <!DOCTYPE html> < ...

随机推荐

  1. RTImageAssets 自动生成 AppIcon 和 @2x @1x 比例图片

    下载地址:https://github.com/rickytan/RTImageAssets 此插件用来生成 @3x 的图片资源对应的 @2x 和 @1x 版本,只要拖拽高清图到 @3x 的位置上,然 ...

  2. vm导入后远程桌面无法登陆域账户

    以本地Admin账户登录,打开C:\Windows\System32\sysprep目录,运行sysprep.exe工具,勾选Generalize,点击OK.系统重启后对Windows重新初始化,生成 ...

  3. VisualSFM for Structure from Motion

    VisualSFM是Changchang Wu编写的使用 Structure from Motion (SfM)进行3D重建的交互界面,具体内容详见http://homes.cs.washington ...

  4. [原]Android打包之跨平台打包

    Android自动打包流程详细图: 在前面一些博客我们知道了如何通过命令行打包,如何通过Eclipse打包,如何通过编写shell脚本来进行打包,但是这些都不能很好的跨平台进行打包. 因Python本 ...

  5. 【转载】linux tail命令的使用方法详解

    本文介绍Linux下tail命令的使用方法.linux tail命令用途是依照要求将指定的文件的最后部分输出到标准设备,通常是终端,通俗讲来,就是把某个档案文件的最后几行显示到终端上,假设该档案有更新 ...

  6. asp.net 客户端上传文件全路径获取方法

    asp.net  获取客户端上传文件全路径方法: eg:F:\test\1.doc 基于浏览器安全问题,浏览器将屏蔽获取客户端文件全路径的方法,只能获取到文件的文件名,如果需要获取全路径则需要另想其他 ...

  7. @media 手机与IPAD与PC

    @media screen and (min-width: 769px) { bindCard{height:28.5em} } @media screen and (min-device-width ...

  8. Connecting my Particle Photon Internet of Things device to the Azure IoT Hub(Translation)

    原文: http://www.hanselman.com/blog/ConnectingMyParticlePhotonInternetOfThingsDeviceToTheAzureIoTHub.a ...

  9. 怎样设置一个DIV在所有层的最上层,最上层DIV

    怎样设置一个DIV在所有层的最上层,最上层DIV,其实很简单,只需要在这个DIV上使用这个样式即可,z-index:99999

  10. 两分钟了解REACTIVEX

    可能在之前,你就已经看过这篇响应式编程的入门.什么?太长?好吧,这都没关系,Rx并不难,你甚至可以自己实现一个这样的框架. 知道数组吧?你当然知道,这就是: [ 14, 9, 5, 2, 10, 13 ...