js中对象引用出现的问题
先看一个特别不符合直觉的代码
<script type="text/javascript">
var a = [1,2,3,4];
var b = [1,2,3,4];
console.log(a==b); //出现false,按照常规理解,a和b应该是一样的,都是[1,2,3,4],同时也说明,js中不能这么判断数组时候相同
</script>
再看代码
<script type="text/javascript">
var a = 3;
var b = 3;
console.log(a==b); //true
</script>
第二段代码为true很好理解,都是3,那第一段代码为何为false,都是[1,2,3,4]呀
----------
在js中,基本类型的变量(有数字,字符串,布尔值)赋值的时候,就是值复制过去,以后相互之间就没有关系了。
比如说:
<script type="text/javascript">
var a = 5;
var b = a; //a是基本类型数据,赋值给b,那么在内存中,b就存了a的值5,以后各走各的路,a,b没有关系了。
b += 5;
console.log(a,b); // 5,10
</script>
<script type="text/javascript">
var a = [1,2,3,4];
var b = a;
var c = [1,2,3,4];
console.log(a==b); //true;
console.log(a==c); //false; //b是a赋值过去的,现在更改b的内容,再看看a
b.push(5);
console.log(a); // [1, 2, 3, 4, 5 ] 很奇怪吧,a也变了啊,这里对a没有操作呀???
</script>
上面的代码,a不是基本类型,是个数组对象,赋给b的时候,改动b也改动了a,真是奇怪。这就是在js中,当a不是基本类型数据时,内存中a存的是一个内存地址,a赋值给b时候,ab共同指向一个内存地址,改动了a,也就改动了b,改动了b,也就改动了a,如下
<script type="text/javascript">
var a = [1,2,3,4];
var b = a;
var c = [1,2,3,4];
console.log(a==b); //true;
console.log(a==c); //false; //b是a赋值过去的,现在更改b的内容,再看看a
b.push(5);
a.push(6);
console.log(a); // [1, 2, 3, 4, 5 ,6 ] 很奇怪吧,a也变了啊,这里对a没有操作呀???
console.log(b); // [1, 2, 3, 4, 5 ,6 ]
console.log(a==b); //true;
</script>
再看一段代码
<script type="text/javascript">
var a = [1,2,3,4];
var b = a; //b是a赋值过去的,现在更改b的内容,再看看a
b = [1,2,3,4,5]; //这里不用b.push(5);看看什么变化
console.log(a); // [1, 2, 3, 4 ] a不变
console.log(b); // [1, 2, 3, 4, 5 ]
console.log(a==b); //false;
</script>
是不是很困惑,不是说了改动b,a也跟着动吗?
第6行代码,不是b对象改动,而是又重新赋值一个对象给了b,b是数组对象的另一个对象实例(只要程序中出现赋值,那就是重新生成),他俩也就没关系了,如果用b的某个方法,改动的b的值,那a和b仍然指向同一个地址!
---------------------------
所有的一切,总结出来一句话:
在js中,基本类型数据,在内存中存的就是个数据
a | 5
b | 5
a,b值相同,就是a==b
但是对象不一样
在内存中,对象存的是个地址,a和b这两个对象相同的话,需要值和地址都相同才可以。
a | 内存指针1
b | 内存指针1
这样ab才相同。
--------------------------
在面向对象程序中,如果用这种方式创建对象,如下
<script type="text/javascript">
function CreatePerson(name){
this.name = name;
this.test = function(){
console.log(this.name);
}
} var my_obj1 = new CreatePerson('张三');
var my_obj2 = new CreatePerson('李四'); alert(my_obj1.test == my_obj2.test); //false //虽然代码上是一样的,但是my_obj1和my_obj2是两个对象实例,他们各自在内存中开辟一个地方,放置test方法,如果对象实例很多,就比较占内存了。 </script>
所以,要更改下,用prototype,在对象中,不同的地方,如属性,写在构造函数里,相同的地方,如方法,用原型来写。如下:
<script type="text/javascript">
function CreatePerson(name){
this.name = name;
} CreatePerson.prototype.test = function(){
console.log(this.name);
} var my_obj1 = new CreatePerson('张三');
var my_obj2 = new CreatePerson('李四'); alert(my_obj1.test == my_obj2.test); //true
my_obj1.test(); // 张三
my_obj2.test(); // 李四 </script>
js中对象引用出现的问题的更多相关文章
- 别再为了this发愁了------JS中的this机制
别再为了this发愁了------JS中的this机制 题记:JavaScript中有很多令人困惑的地方,或者叫做机制.但是,就是这些东西让JavaScript显得那么美好而与众不同.比方说函数也是对 ...
- JS中的this用法详解
随着对js的深入学习和使用,你会发现它里面包含了很多令人困惑的机制,比如对象.闭包.原型链继承等等,而这其中肯定包含令你现在或者曾经费解的this,如果你不把心一横,花点时间还真不明白这个this的用 ...
- js中的数据类型及其转换
Js中的数据类型 Js中的数据类型一共有六种,即number,string,boolean,underfine,null,object. 一,number Number数据类型指的是数字,可以为整型, ...
- Javascript基础 - js中曾经忽略的知识点
深入那些曾经忽略的Javascript知识 1. parseInt(string, [radix]),parseFloat(string) 一般我们省略第二个参数,parseInt(‘100’) == ...
- JS中如何进行对象的深拷贝
在JS中,一般的=号传递的都是对象/数组的引用,并没有真正地拷贝一个对象,那如何进行对象的深度拷贝呢?如果你对此也有疑问,这篇文章或许能够帮助到你 一.对象引用.浅层拷贝与深层拷贝的区别 js的对象引 ...
- JS中让新手倍感震惊、违反直觉、出乎意料、的一些知识点汇总记录
本文记录在自己学习js过程中,违反直觉,出乎意料,倍感震惊的知识点.当然,不了解这个知识点,很容易出错,因为毕竟违反直觉,出乎意料,倍感震惊嘛! 1. 两个内容一样的数组竟然不相等? var a = ...
- JS中的六大数据类型
js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object). typeof 操作符 由于js中的变量是松 ...
- JS中变量的存储
JS中的变量是保存在栈内存中的 基本数据类型的值直接在栈内存中存储: 值与值之间是独立存在的,修改一个变量不会影响其他变量: var a=20; var b=a; a++; 对象(引用数据类型)是保存 ...
- 别再为了this发愁了:JS中的this机制
题记:JavaScript中有很多令人困惑的地方,或者叫做机制.但是,就是这些东西让JavaScript显得那么美好而与众不同.比方说函数也是对象.闭包.原型链继承等等,而这其中就包括颇让人费解的th ...
随机推荐
- Virtual Box虚拟机Ubuntu系统安装及基本配置
Linux简介 什么是 Linux? Linux:世界上不仅只有一个 Windows 操作系统,还有 Linux.mac.Unix 等操作系统.桌面操作系统下 Windows 是霸主,而 Linux ...
- Docker最全教程之树莓派和Docker(十五)
前言 树莓派(Raspberry Pi)是一台卡片电脑(只有信用卡大小),我们可以使用树莓派做很多事情,比如智能家居的中控.航空器.BT下载器.挖矿机.智能机器人.小型服务器(花生壳+网站)等等. 目 ...
- Javascript 面向对象(共有方法,私有方法,特权方法,静态属性和方法,静态类)示例讲解
一,私有属性和方法 私有方法:私有方法本身是可以访问类内部的所有属性(即私有属性和公有属性),但是私有方法是不可以在类的外部被调用. <script> /* * 私有方法:私有方法本身是可 ...
- 包(package)以及面向对象三个基本特征(继承)的介绍
1.包(package) 包(package) 用于管理程序中的类,主要用于解决类的同名问题.包也可以看成一个目录. 包的作用 [1] 防止命名冲突. [2] 允许类组成一个单元(模块),便于管理和维 ...
- MySQL字段操作与数据处理
一,对字段的操作 1.拼接字段:Concat()函数 多数DBMS使用 + 或者 || 来实现拼接,而MySQL使用 Concat() 函数来实现拼接. 实例: Concat()函数拼接时加上的字符需 ...
- css3 笔记 背景
.div1 { height: 80px; background: linear-gradient( 135deg, transparent 0, transparent 49.5%, green 4 ...
- 总结安装webpack过程中遇到的错误及解决方案
1.安装不成功的报错: 解决方案:清除缓存 2.打包不成功: 解决方案:填写打包路径时的“__dirname”有两个下划线 3.打包报错: 解决方案:正确填写路径为“./style.css”
- 设置input中placeholder的样式(placeholder设置字体)
方法: 代码示例: .input::-webkit-input-placeholder { font-size: 3.73333333vw; color: #cccccc; } .input:-moz ...
- C# 离线人脸识别 ArcSoft V2.0 Demo
本来打算做个C#版demo,但没用成功.使用虹软最新人脸识别技术开发完成 过程如下: 1. 传入一张单人脸照片: 2.调用检测人脸函数ASFDetectFaces,成功返回人脸信息的指针: 3.使用 ...
- Java:API文档;文档注释中的javadoc标记;官方API;自己动手给项目建一个API文档
1.什么是API文档 在Java语言中有3种注释 //单行注释 /* 多行注释 */ /** * 文档注释 */ API(应用程序接口)文档就是用javadoc命令提取文档注释生成的,html格式,用 ...