null == null 或者 [] == [] 或者{} == {} 或者alert(1|| 2) 或者alert(1&& 2) 结果及原理
相信面试的小伙伴们都会遇到此头大的问题,是不是很想骂一句面试官:你白痴啊,鬼都用不着的东西拿来问,你还别说,这些看似用不着的东西却包含着最基础的原理,那我们来理一理。
1.alert(1||2)和 alert(1&& 2)
话不多说,实践是检验真理的唯一标准

非0 即true ,|| 是一真为真,即弹出1;

alert(1&& 2)结果为什么弹个2 呢?
1)只要 ‘&&’ 前面是false ,无论 ‘&&’ 后面是true 还是false,结果都返回 ‘&&’前面的值
2)只要 ‘&&’前面是true ,无论 ‘&&’ 后面是true 还是false ,结果返回 ‘&&’后面的值。
如果实在记不住,就跟|| 运算相反好了。!(一真为真 ) 为&& 结果。
2. null == null 或者 [] == [] 或者{} == {} ?
结果是 null == null true ; [] == [] 或者{} == {} false;
先来了解两个概念:栈 stack 和 堆 heap
栈(stack):1) 先进后出; 2) 自动分配内存空间,3) 由系统自动释放;4) 使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完立即释放。
堆(heap):队列优先,1) 先进先出;2) 动态分配内存,大小不定也不会自动释放;3)存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定;一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。
Undefined / Null / Boolean / Number / String,它们是直接按值存放的,可以直接访问
当我们需要访问引用数据类型 (对象 / 数组 / 函数) 的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。
变量a实际保存的是指向堆内存中对象的一个指针,而b保存的是指向堆内存中另一个对象的一个指针;虽然这两个对象的值是一样的,但它们是独立的2个对象,占了2份内存空间;所以 a==b 为 false。
如果 var a = {}; var b = a; 这时变量b复制了变量a保存的指针,它们都指向堆内存中同一个对象;所以 a==b 为 true。
到这里问题已经解决了,但我们需要深入学习一下;
3. 传值与传址?
基本类型与引用类型最大的区别实际就是 传值与传址的区别。
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); // 1
b[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堆内存中
4. 浅拷贝
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); //zyj
console.log(b.hobby); //['reading', 'coffee']
console.log(b.age); //18
console.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对象的内存空间。
5. 深拷贝
在实际编码中,我们不希望父子对象之间产生关联,这时就用到深拷贝。既然属性值类型是数组或对象时只会传址,那么就可以用递归来解决这个问题,把父对象中所有属于对象的属性类型遍历赋给子对象即可。代码如下:
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
null == null 或者 [] == [] 或者{} == {} 或者alert(1|| 2) 或者alert(1&& 2) 结果及原理的更多相关文章
- 数据库中is null(is not null)与=null(!=null)的区别
在标准SQL语言(ANIS SQL)SQL-92规定的Null值的比较取值结果都为False,既Null=Null取值也是False.NULL在这里是一种未知值,千变万化的变量,不是“空”这一个定值! ...
- unity, Graphics.Blit (null, null, mat,0);
我使用 Graphics.Blit (null, finalRT, mat); 合成出一张finalRT,然后将finalRT用在editor脚本的OnInspector中使用 Graphics.Dr ...
- PHP中的逻辑判断函数empty() isset() is_null() ==NULL ===NULL
1.empty() header("Content-type: text/html; charset=utf-8"); if(!empty($data)){ //empty() 未 ...
- 如何解决数据库中,数字+null=null
如何解决数据库中,数字+null=null 我使用SQLServer,做一个 update 操作,累计一个数.在数据库中,为了方便,数据库中这个字段我设为允许为空,并且设置了默认值为 0 .但是在新增 ...
- SSIS ->> Null & Null Functions
SSIS不支持值为NULL的变量.每种类型的变量都有自己的默认值. 做了一个测试,用一个Execute SQL Task输出一个NULL值给A变量,然后把A变量传到到另外一个Execute SQL T ...
- iOS解析数据判断nil NULL Null的方法
+ (BOOL)isNil:(NSObject*)obj { if (obj == nil || obj == NULL) { return YES; } if ([obj isKindOfClass ...
- Convert.ToString(null) => null
{ string str0 = Convert.ToString(null); Console.WriteLine("0,{0}", str0); if (str0==" ...
- 【编程技巧】alert vs Ext.Msg.alert
alert会阻塞程序的运行. Ext.Msg.alert是异步的,它的调用并不会停止浏览器中代码的执行.
- js 重写alert 兼容iphone使得alert 不带src
<script> window.alert = function(name){ var iframe = document.createElement("IFRAME" ...
随机推荐
- python调用tushare获取沪深A股票资金流向数据
接口:moneyflow 描述:获取沪深A股票资金流向数据,分析大单小单成交情况,用于判别资金动向 限量:单次最大提取4000行记录,总量不限制 积分:用户需要至少1500积分才可以调取,基础积分有流 ...
- join(long)方法和sleep(long)方法的比较
join(long)方法的源代码 public final synchronized void join(long millis) throws InterruptedException { long ...
- PAT 乙级练习题1002. 写出这个数 (20)
1002. 写出这个数 (20) 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式 ...
- js浮点金额计算精度
在js中进行以元为单位进行浮点数计算时,会产生精度问题,例如: console.log(0.1+0.2) 结果为:0.30000000000000004 大多数编程语言计算采用的是IEEE 754 标 ...
- String转list
String l = "63, 47, 51, 35, 36, 52, 37, 53, 38, 54, 39, 55, 40, 56, 41, 57, 42";List<In ...
- 第五章 配置私有仓库Harbor
一.Harbor 安装(尚硅谷资料) 安装:Harbor 官方地址:官方地址:https://github.com/vmware/harbor/releases 1.解压软件包 tar xvf har ...
- shell script test指令的测试功能 &和&&,|和|| 区别 变量名赋值=号前后的空格问题(天坑)
小程序告一段落,达到阶段性目标.下一步继续Linux的学习....脑子不够用啊...真费... 书中介绍..检测系统某些文件或者相关属性时,用test指令.. 例如.测试某个文档目录是否存在可以 t ...
- MySql为某个表增加rownumber
在mySql中,假设表名为tblA,则 select @x:=@x+1 as rownumber, a.* from (select @x:=0) b, tblA a 此语句执行后,则每行数据之前都会 ...
- 记录常用的linux命令
原文链接:https://www.cnblogs.com/suger43894/p/11024594.html 系统信息相关 date 显示系统日期 cat /proc/mounts 显示已加载的文件 ...
- QDomDocument::clear()的调用,会导致关闭程序时崩溃!!!
//读一份xml前,先清理m_Doc[QDomDocument] bool XmlIO::xmlRead(QString &errmsg) { m_mutex.lock(); // m_Doc ...