var a = function() {console.log(11)};
var b = function() {console.log(11)};
console.log( a==b ); //falseconsole.log( {}=={} ); //false
console.log( []==[] ); //false

如你所见,上述三个例子结果都为false。

相信很多人都碰到过上述情况,像我这种基本功不太扎实的小白,估计都会看的一脸懵吧。别着急,本博客就是来解决问题的。

首先,先来了解两个概念:栈 stack 和 堆 heap。

堆、栈

栈(stack):先进后出;自动分配内存空间,由系统自动释放;使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完立即释放。

堆(heap):队列优先,先进先出;动态分配内存,大小不定也不会自动释放;存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定;一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。

js中基本数据类型和引用数据类型

基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

Undefined / Null / Boolean / Number / String,它们是直接按值存放的,可以直接访问。

引用类型:存放在堆内存中的对象;每个空间大小不一样,根据情况进行特定的分配。

当我们需要访问引用数据类型 (对象 / 数组 / 函数) 的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据

所以,现在就可以解释 var a = function(){}; var b = function(){}; a==b 为false了。

变量a实际保存的是指向堆内存中对象的一个指针,而b保存的是指向堆内存中另一个对象的一个指针;虽然这两个对象的值是一样的,但它们是独立的2个对象,占了2份内存空间;所以 a==b 为 false。

如果 var a = {}; var b = a; 这时变量b复制了变量a保存的指针,它们都指向堆内存中同一个对象;所以 a==b 为 true。

传值与传址

基本类型与引用类型最大的区别实际就是 传值与传址的区别。

var a = [1,2,3,4,5];
var b = a;
var c = a[0];
console.log(b);  // [1,2,3,4,5]
console.log(c);  // 1b[4] = 6;
c = 7;
console.log(a[4]);  //6
console.log(a[0]);  //1

从上面代码可以得知,当改变b中的数据时,a也发生了变化;但是当我们改变c的数值时,a却没有发生改变。

这就是传值与传址的区别。因为a是数组,属于引用类型,所以a给b传的是栈中的地址,而不是堆内存中的对象。而c仅仅是从a堆内存中获取的一个数值,并保存在栈中。所以b修改的时候,会根据地址回到a堆内存中修改;c则直接在栈中修改,并且不能指向a堆内存中。

讲到栈和堆,不得不提浅拷贝和深拷贝。

浅拷贝

当我们使用对象拷贝时,如果属性是对象或数组时,这时我们传递的只是一个地址。因此子对象在访问该属性时,会根据地址回溯到父对象指向的堆内存中,即父子对象发生了关联,两者的属性值会指向同一内存空间。

var a = {name: 'zyj'};function Copy(q) {var m = {};for(var i in q) {m[i] = q[i];}return m;}a.hobby = ['reading', 'coffee'];var b = Copy(a);b.age = 18;console.log(b.name);  //zyjconsole.log(b.hobby);  //['reading', 'coffee']console.log(b.age);  //18console.log(a.age);  //undefined

a对象中的name属性值为字符串,hobby为数组。a拷贝到b,两个属性均能顺利拷贝。 给b对象新增一个 number类型的属性age时,b能够正常修改,而a中无定义。说明 子对象 b 的 age 并没有关联到 父对象 a 中,所以为undefined。

b.hobby.push('dancing');
console.log(b.hobby); //['reading', 'coffee', 'dancing']
console.log(a.hobby); //['reading', 'coffee', 'dancing']

但是,若修改的属性为 对象或数组时,那么 父子对象之间就会发生关联。其在内存的状态,见下图。

原因是 age的值属于基本类型,所以拷贝的时候传递的是该数据值;但hobby的值是堆内存中的对象,所以hobby在拷贝的时候传递的是指向hobby对象的地址,无论复制多少hobby,其值始终是指向父对象的hobby对象的内存空间。

深拷贝

在实际编码中,我们不希望父子对象之间产生关联,这时就用到深拷贝。既然属性值类型是数组或对象时只会传址,那么就可以用递归来解决这个问题,把父对象中所有属于对象的属性类型遍历赋给子对象即可。代码如下:

var a = {name: 'zyj'};function Copy(q, m) {var m = m || {};for(var i in q) {if(typeof q[i] === 'object') {m[i] = (q[i].constructor === Array)?[]:{};Copy(q[i], m[i]);}else {m[i] = q[i];}}return m;}a.hobby = ['reading', 'coffee'];var b = {};b = Copy(a, b);b.hobby.push('dancing');console.log(b.hobby); //['reading', 'coffee', 'dancing']console.log(a.hobby); //['reading', 'coffee']

修改b子对象的hobby数组时,没有使a父对象中的hobby数组新增一个值,即子对象没有影响到父对象a中的hobby,存储模式如下:

{} == {} 结果为什么是false?相关推荐

  1. Android JSON解析并展现在listactivity实例

    本次要展示的实例是:从一个json文件解析两个字段 并放在具有两个展示容器listview上 json文件(来自公司的商业应用,抓包看得到的json,也没有加密,应该没有侵权神马的吧=.=  反正博客 ...

  2. 基因数据处理51之cs-bwamem集群版运行*

    将master的local改为集群就可以了. 集群运行结果: 问题: 匹配50条的时候,bwa和snap都是生成50条.但是cs-bwamem会生成492条,其中25和50条重读的很多,匹配位置不同. ...

  3. java学习笔记-基础知识-2023.3.29

    学习网站:https://www.sxt.cn/Java_jQuery_in_action/History_Direction.html 刷题网站 牛客网专题-spring java sql 第一章 ...

  4. Multiple substitutions specified in non-positional format; did you mean to add the formatted=”false”

    make 编译android代码的出现这样的错误 这个问题可能是跟android 的版本有关系就是xml 中的String.xml文件的文字使用%s 无法识别引起的, 不过有些版本可以识别 下面的就有 ...

  5. ASP.NET 4.0: 请求验证模式变化导致ValidateRequest=false失效

    ASP.NET请求验证功能可以给我提供应用程序的安全保证,避免站点受到XSS的攻击.但是在一些情况下,我们需要禁用这个功能,比如我们需要使用HtmlEditor来让用户输入一些HTML文本,这时候AS ...

  6. intval0.57100 php_php中0,'',null,false,true,FLASE,TREU,array()的相等恒等学习

    //比较值 '' NULL 0 false true FALSE TRUE //相等判断 //'' == NULL == 0 == false (相等) //array() = 0 == NULL = ...

  7. 回文数:给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

    1.方法一:将数字转换为字符串,并检查字符串是否为回文 #include<iostream> using namespace std;class Solution { public:boo ...

  8. 【全网之最】最短代码清除数组中的假、空值(0、空、null、undefined、false)

    [1,0,,null,undefined,false].filter(Boolean);//[1]

  9. 好理解的Java内存虚假共享(False Sharing)性能损耗以及解决方案

    虚假共享(False Sharing)也有人翻译为伪共享 参考 https://en.wikipedia.org/wiki/False_sharing 在计算机科学中,虚假共享是一种性能降低的使用模式 ...

  10. request.getSession(false)到底返回什么

    HttpSession session = request.getSession(false); 很明显传false如果session不存在返回Null.

最新文章

  1. “基因编辑婴儿”惹争议,你或许不知道机器学习在脱靶效应中的作用?
  2. 京东首页302 Found报错 监控宝教你如何第一时间发现
  3. 5.java.lang.IndexOutOfBoundsException(数组下标越界异常)
  4. DHCP的基本介绍以及在HC3上配置DHCP中继和DHCP snooping
  5. java 制作 winrar,Java使用winrar解压缩
  6. Runtime Error VS Accepted (大整数排序 )
  7. Android 系统性能优化(40)---Android LowMemoryKiller原理分析
  8. 快速从入门到精通!mysql删除语句姓李的语句
  9. 前端基础8:HTML5新增标签及CSS3新属性 viewport 动画
  10. Java学习笔记十:Java的数组以及操作数组
  11. AifbdScore智能AI曲谱乐谱播放识别SDK midi曲谱 应用开发 五线谱 六线谱 四线谱播放
  12. 出售永磁同步电机(pmsm)模型预测控制(MPC)matlab/simulink仿真模型,转速控制,电流控制,转矩控制,直接预测控制(有限集模型预测控制)(这单矢量和双矢量,三矢量),无差拍,foc矢
  13. 前端:项目 文件 文件夹 命名规范
  14. 网路工程师工作中常用的几款软件
  15. mysql命令行集锦
  16. 【Node.js】实现微信小程序在线支付功能
  17. Javascript特效之可翻阅上一条下一条的动态文字
  18. c语言程序打不开如何修复,处理win7中打不开程序修复0xc0000142错误代码的问题
  19. 如何营造办公室的友好氛围
  20. python解决迅雷下载限制的方法

热门文章

  1. 关于三菱GXWORK安装失败或者安装向导被中断的解决办法
  2. 浩顺小票网络打印机安装流程
  3. yagmail发邮件辅助系统(一)
  4. 把img映象文件转化为dcm格式文件
  5. 将一个dcm格式的医学影像文件处理为一个png格式的图像和一个xml格式的文件
  6. 瞬变电磁数据读取显示,正演计算,及基础处理DLL文件调用
  7. 怎么修复录音笔(设备)损坏的WAV或MP3文件0字节文件
  8. 用cocos2d-x模拟单摆运动的程序
  9. 电力系统中惯量和阻尼的分类以及两者不足的危害
  10. Unsupervised Monocular Depth and Ego-motion Learning with Structure and Semantics 之论文详解