Javascript对象赋值操作
首先,我们还是举个例子来说明对象赋值操作的问题吧:
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对象赋值操作的更多相关文章
- C风格字符串和C++ string 对象赋值操作的性能比较
<<C++ Primer>> 第四版 Exercise Section 4.3.1 部分Exercise 4.2.9 习题如下: 在自己本机执行如下程序,记录程序执行时间: # ...
- javascript数组赋值操作的坑
描述:数组对象赋值,即arr1=[{},{},{}]这种数据结构的对象赋值,将arr1赋值给arr2:然后删除arr2里的元素 一.最常用的= arr2 = arr1; detect(val) { l ...
- javascript数组赋值操作
最近在司徒正美的<javascript框架设计>,在里面发现了一个段代码 ...... var _len = arr1.length; while (_len) { arr2[--_len ...
- JavaScript对象属性赋值操作的逻辑
对象进行属性赋值操作时,其执行逻辑如下所示: 1. 当前对象中是否有该属性?有,进行赋值操作:没有,进行下一步判断. 2. 对象的原型链中是否有该属性?没有,在当前对象上创建该属性,并赋值:有,进行下 ...
- 深入理解javascript对象系列第二篇——属性操作
× 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...
- javascript:面向对象和常见内置对象及操作
本文内容: 面向对象 常见内置对象及操作 首发日期:2018-05-11 面向对象: JavaScript 是面向对象的编程语言 (OOP).OOP 语言使我们有能力定义自己的对象和变量类型. 对象是 ...
- jquery实现点击展开列表同时隐藏其他列表 js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象
这篇文章主要介绍了jquery实现点击展开列表同时隐藏其他列表的方法,涉及jquery鼠标事件及节点的遍历与属性操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了jquery实现点击 ...
- JavaScript 对象的创建和操作
<script> // 对象是属性的无序集合,每个属性都是一个名/值对. 属性名称是一个字符串. // 对象种类 // 内置对象(nativ ...
- Javascript对象的方法赋值
Javascript对象编程学习中,一直不能很好的掌握对象的属性(property)和方法(method).今天在写代码过程中,又犯了一个低级错误. <!DOCTYPE html> < ...
随机推荐
- RTImageAssets 自动生成 AppIcon 和 @2x @1x 比例图片
下载地址:https://github.com/rickytan/RTImageAssets 此插件用来生成 @3x 的图片资源对应的 @2x 和 @1x 版本,只要拖拽高清图到 @3x 的位置上,然 ...
- vm导入后远程桌面无法登陆域账户
以本地Admin账户登录,打开C:\Windows\System32\sysprep目录,运行sysprep.exe工具,勾选Generalize,点击OK.系统重启后对Windows重新初始化,生成 ...
- VisualSFM for Structure from Motion
VisualSFM是Changchang Wu编写的使用 Structure from Motion (SfM)进行3D重建的交互界面,具体内容详见http://homes.cs.washington ...
- [原]Android打包之跨平台打包
Android自动打包流程详细图: 在前面一些博客我们知道了如何通过命令行打包,如何通过Eclipse打包,如何通过编写shell脚本来进行打包,但是这些都不能很好的跨平台进行打包. 因Python本 ...
- 【转载】linux tail命令的使用方法详解
本文介绍Linux下tail命令的使用方法.linux tail命令用途是依照要求将指定的文件的最后部分输出到标准设备,通常是终端,通俗讲来,就是把某个档案文件的最后几行显示到终端上,假设该档案有更新 ...
- asp.net 客户端上传文件全路径获取方法
asp.net 获取客户端上传文件全路径方法: eg:F:\test\1.doc 基于浏览器安全问题,浏览器将屏蔽获取客户端文件全路径的方法,只能获取到文件的文件名,如果需要获取全路径则需要另想其他 ...
- @media 手机与IPAD与PC
@media screen and (min-width: 769px) { bindCard{height:28.5em} } @media screen and (min-device-width ...
- Connecting my Particle Photon Internet of Things device to the Azure IoT Hub(Translation)
原文: http://www.hanselman.com/blog/ConnectingMyParticlePhotonInternetOfThingsDeviceToTheAzureIoTHub.a ...
- 怎样设置一个DIV在所有层的最上层,最上层DIV
怎样设置一个DIV在所有层的最上层,最上层DIV,其实很简单,只需要在这个DIV上使用这个样式即可,z-index:99999
- 两分钟了解REACTIVEX
可能在之前,你就已经看过这篇响应式编程的入门.什么?太长?好吧,这都没关系,Rx并不难,你甚至可以自己实现一个这样的框架. 知道数组吧?你当然知道,这就是: [ 14, 9, 5, 2, 10, 13 ...