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

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. Android Studio NDK 学习之接受Java传入的字符串

    本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫Prompt,其 ...

  2. textView字体颜色根据不同状态显示不同颜色

    XML file saved at res/color/button_text.xml: <?xml version="1.0" encoding="utf-8&q ...

  3. SmartJS 系列规划分享和背景介绍

    发布了smartjs后,有朋友问:“没看懂究竟是干嘛的”.唉,打击了,每次我都想高唱其实你不懂我的心. 今天把相关的东西都整理了一遍,给大家介绍一下.里面绝大多数都已经实现过,有些则是有新的思路重做或 ...

  4. ECMAScript5新增对象语法糖getter和setter

    在新的ECMAScript5中新添加了两个语法糖,这两个语法糖是这样的. var obj = (function(){ var num = 10; return { get n(){ return n ...

  5. Shader的语法

    Shader "name" { [Properties] Subshaders [Fallback] }(1)Properties:{ Property [Property ... ...

  6. WCF安全2-非对称加密

    概述: 数字签名和加密依赖于相应的加密算法 自变量:加密前的数据.密钥 因变量:加密后的数据 加密算法分类:根据加密和解密这两种步骤采用的密钥的是否相同进行分类 相同:对称加密 不相同:非对称加密 非 ...

  7. 【转载】关于 Ubuntu 的小知识分享

    转载自:http://os.51cto.com/art/201307/402197.htm 一.默认开机直接进入到Ubuntu命令行界面 安装Ubuntu后,开机会默认进入到图形界面,如果不喜欢图形界 ...

  8. Testing - Selenium

    Selenium http://www.seleniumhq.org/ User Guide http://www.seleniumhq.org/docs/ Webdriver中文社区 http:// ...

  9. Breach - HTML5 时代,基于 JS 编写的浏览器

    Breach 是一款属于 HTML5 时代的开源浏览器项目,,完全用 Javascript 编写的.免费.模块化.易于扩展.这个浏览器中的一切都是模块,Web 应用程序在其自己的进程运行.通过选择合适 ...

  10. 使用 PSD Validator 在线校验 PSD 文件的质量

     PSD Validator 可以帮助你在线校验 PSD 文件的质量,使用的规则来自 Photoshop Etiquette.Photoshop Etiquette 整理了 PSD 文件的规范,例如删 ...