JavaScript高级程序设计-第3版-中 有这么一段话:

在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的①。

① 这种说法不严密,当复制保存着对象的某个变量时,操作的是对象的引用。但在为对象添加属性时,操作的是实际的对象。

这里的重点是①的注释,初次看的时候没有理解,后来理解了,举个例子:

先看①的前半句,比较好理解:

当复制保存着对象的某个变量时,操作的是对象的引用。

var a = { n: 2 };    //这里把 { n: 2 } 赋值给 a,实际上是把 a 的指针指向 { n: 2 }
var b = a; //这里把 a 赋值给 b,实际上是把 b 的指针指向 a 的指针,最终是把 b 的指针指向上一个对象{ n: 2 };
var c = { n: 2 }; //这里把 { n: 2 } 赋值给 c,实际上是把 c 的指针指向 { n: 2 } ,但是这个对象和前面的对象不等,只有指针指向同一个对象时,两个对象才相等;
console.log(b); //{ n: 2 }
console.log(a === b); //true,b 保存是指针,a 也是,两个指针指向同一个对象,所以相等,所以 a,b 保存的都是同一个对象的引用
console.log(a === c); //false ,a,c 看起来相等,实际上是两个指针指向不同的对象;彼此没有发生引用关系;

这里还没有涉及到 ①的后半句:

但在为对象添加属性时,操作的是实际的对象。

这句话用来解释下面问题就很有用了:

var a = { n: 2 };
var b = a;
a.x = 1; // 操作的是对象 a 的引用还是实际对象 { n: 2 }?
console.log(a); // { n: 2, x: 1 }
console.log(b); // { n: 2, x: 1 }

如果按书上原话,操作的是对象 a 的引用,那这里就是把 a 由指向 { n: 2 } 转为 指向 { n: 2, x: 1 },如果这个逻辑是正确的,那么 b 应该还是 { n: 2 } ,然而事实不是,证明这个逻辑不对;

如果按照①的逻辑,操作的是实际的对象,那这里就是把 { n: 2 } 这个对象变成了 { n: 2, x: 1 },而 a,b 本身就指向的这个对象,所以 a,b 的输出自然就是 { n: 2, x: 1 },逻辑正确。

所以,当复制保存着对象的某个变量时,操作的是对象的引用。但在为对象添加属性时,操作的是实际的对象。

参考资料:

JavaScript高级程序设计-第3版-中

js 操作对象的引用和操作实际对象的区分的更多相关文章

  1. JS对象的引用,对象的拷贝

    目录 一.场景 二.浅拷贝 三.深拷贝 一.场景 除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝 将一个对象赋值给另外一个对象. var a = [1,2,3]; ...

  2. Python 对象的引用计数和拷贝

    Python 对象的引用计数和拷贝 Python是一种面向对象的语言,包括变量.函数.类.模块等等一切皆对象. 在python中,每个对象有以下三个属性: 1.id,每个对象都有一个唯一的身份标识自己 ...

  3. Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数

    本文參考<Android系统源码情景分析>,作者罗升阳. 一.Binder库(libbinder)代码: ~/Android/frameworks/base/libs/binder --- ...

  4. C#中字符串的处理,对象的引用及继承(Tenth day)

    又进入到了新的一周,现在到总结的时间了,继续为大家总结一下今天在云和学院所学的知识. 理论: StringBuilder 和 String 的区别    String 在进行运算时(如赋值.拼接等)会 ...

  5. 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用

    先看第一种情况:返回一个局部对象的引用.它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的.也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的.所谓生命空间,是指它们所在的 ...

  6. java String不可变对象,但StringBuffer是可变对象

    什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不 ...

  7. js学习--DOM操作详解大全一(浏览器对象)

    一.客户端中的window对象 window对象表示当前浏览器的窗口,它是一个顶级对象,我们创建的所有对象.函数.变量都是window对象的成员. window对象自带了一些非常有用的方法.属性. w ...

  8. JS中的DOM对象及JS对document对像的操作

    DOM对象 windows:属性:opener(打开者) 方法:open().close(),setTimeout().setInterval()... location:属性:href 方法:rel ...

  9. js对象,数组,字符串的操作

    循环绑定=>变量污染 for (var i = 0;i<lis.length;i++){ lis[i].index = i;#给页面元素对象添加一个任意属性(保留索引的属性index) # ...

随机推荐

  1. java递归算法实现拼装树形JSON数据

    有时候页面需要使用jQuery easy ui中的combotree,需要给combotree提供一个JSON数据,使用如下方法(递归)实现(下面是dao层的实现层): /** * 根据表名和父id拼 ...

  2. unity, Rigidbody.constraints

    一,同时施加多个限制: 用按位或(bitwise OR)实现,例如: GetComponent<Rigidbody>().constraints=RigidbodyConstraints. ...

  3. CentOS-6.5下安装navicat for mysql

    一.安装前准备 安装epel源        安装wine        如果不安装wine,则可能会出现安装完navicat for mysql后无法启动的情况. 二.安装epel源 cd /tmp ...

  4. CYQ学习主要摘要2

    数据库配置假设如下: <connectionStrings>         <add name="Conn" connectionString="Se ...

  5. 线程相关函数(4)-pthread_mutex_lock(), pthread_mutex_unlock() 互斥锁

    互斥锁实例: #include <pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int pthread_mutex ...

  6. LINK : fatal error LNK1104

    今天本来想试试opencv的,于是就在自己的机子上部署一下试试,结果一直遇到这个错误:LINK : fatal error LNK1104 环境:win7 64位 vs2012 opencv 2.4. ...

  7. Windows操作系统下 使用c++ WIN32API禁用控制台最小化和关闭按钮

    #include<Windows.h> //屏蔽控制台最小按钮和关闭按钮 HWND hwnd = GetConsoleWindow(); HMENU hmenu = GetSystemMe ...

  8. scp采用无密码在两台linux服务器之间传输数据

    一.root用户: 1. 在主机A上执行如下命令来生成配对密钥: ssh-keygen -t rsa 按照提示操作,注意,不要输入passphrase.提示信息如下 Generating public ...

  9. Linux解决删除文件后空间没有释放问题_端口占用问题

    使用命令 (1) losf | grep deleted 查询所有已经删除但是还未释放空间的进程,找到容量最大的线程,kill -9 pid 然后等待容量释放 (2) netstat -ano | g ...

  10. div随页面滚动遇顶固定的两种方法(js&jQuery)

    一.遇顶固定的例子 我一直以为是某个div或层随屏幕滚动,遇顶则固定,离开浏览器顶部又还原这样的例子其实不少,其实它的名字叫“层的智能浮动效果”.目前我们在国内的商业网站上就常常看到这样的效果了.例如 ...