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

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. 重构第2天:方法搬移(Move Method)

    现在就重构来说是非常普通的,虽然我们经常会漏掉或忽略一些需要重构的地方.方法搬移,正如所定义的那样,把方法搬移到更适合他的位置.让我们看看下面这一段重构前的代码: 理解:方法搬移,正如所定义的那样,把 ...

  2. Qt的零碎知识

    1.QObject是所有Qt对象的基类,他给C++的类带来了若干新的功能.使用Q_OBJECT宏能声明一个C++类为一个QObject.如: class Notepad : public QMainW ...

  3. Nginx+Keepalived实现站点高可用

    http://seanlook.com/2015/05/18/nginx-keepalived-ha/ http://blog.csdn.net/conquer0715/article/details ...

  4. 让我们一起Go(十)

    前言: 本系列还没流产,继续难产中,哈哈,只怪我没专心,在期间又偷偷去学了python,ruby,scala,haskell这几种语言,如果你不幸是本系列的读者,那么你得慢慢等后面的了,等不及可以过几 ...

  5. 【原创】试用十天被Pass所带来的启示

    试用十天被Pass所带来的启示   招聘是门学问,很多人在研究,也有很多方案,不过面对人员难聘问题,很多方法又不灵了.于是我们采用了降低标准方案,扩招进来一些人员,于是问题又来了,想不想听我亲身经历的 ...

  6. Cwinux源码解析(一)

    我在我的个人博客发表了新的文章,欢迎各位读者批评指正. Cwinux源码解析(一)

  7. Office Web Apps Server 概述

    Office Web Apps Server 是新的 Office 服务器产品,它提供 Word.PowerPoint.Excel 和 OneNote 的基于浏览器的版本.单个 Office Web ...

  8. Centos7 禁止firewalld并使用iptables 作默认防火墙

    一.停止并禁用firewalld [root@test ~]# systemctl stop firewalld [root@test ~]# systemctl disable firewalld ...

  9. .net core 1.0 Web MVC 自定义认证过程

    通过官方的介绍可知,若要本地开始部署搭建一个基于.net core 1.0的Web应用,需要下载dotnet SDK,或在Visual Studio IDE之上安装相关插件以布置开发环境.为了使开发环 ...

  10. Python+Selenium进行UI自动化测试项目中,常用的小技巧4:日志打印,longging模块(控制台和文件同时输出)

    在前段时间,为了给项目中加入日志功能,就想到了 logging 模块,百度logging一大推,都是各种复制的,并没有找到自己想要的结果:我的目的很简单,就是:在把日志写入文件的同时在控制台输出,更加 ...