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" ...
随机推荐
- 抓取猫眼TOP100的数据
import requests import re import json from multiprocessing import Pool from multiprocessing import M ...
- Java-技术专区-技术栈分析辨证方法
1.好多公司动不动就JVM.高并发.分布式.微服务等等,我没有实际经验. 2.从事Java开发三年了,目前的职位是高级Java工程师,感觉技术和工资都到了瓶颈,对以后的发展方向有些迷茫. 3.加班时间 ...
- 《构建之法》需求分析 读书笔记 Week6
本周选读<构建之法>第8章——需求分析.由于有团队项目初期调研阶段做调查问卷的经历,这一章节中很多知识点我都比较有体会.对我而言,这一章节最有价值的内容就是厘清了关于需求分析的两个误解和近 ...
- Ubuntu 14.04 Sublime Text3 Java编译运行(最简单的方法)
Sublime,结果发现只能编译,无法直接运行,于是就在网上搜解决方法,发现大部分方法都是告诉你要进入Java.sublime-packag这个文件,然后再修改JavaC.sublime-build, ...
- Codeforces 1167F 计算贡献
题意:给你一个函数f,计算∑(i = 1 to n)(j = i to n) f(i, j).f(i, j)的定义是:取出数组中i位置到j位置的所有元素,排好序,然后把排好序的位置 * 元素 加起来. ...
- C++中的delete加深认识
delete操作: 我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身. 1.假如你不去释放,那么该区域的内存始终不能被其他数据所使用.2.指向该内存的指针是个局部变 ...
- nodejs 静态资源文件与登陆交互
server2.js var express=require('express'); var expressStatic=require('express-static'); var server=e ...
- VS2017编译64位CloudCompare
需求:编译一个支持读写las点云的CC,然后再开发CC插件实现业务功能. 编译环境: 1.Windows 10 2.Visual Studio 2017 Community 3.Qt 5.9.4 开源 ...
- springboot集成使用rabbitmq笔记(2.rabbitmq使用)
使用rabbitmq笔记一 使用rabbitmq笔记二 使用rabbitmq笔记三 1.引入包 <dependencies> <dependency> <groupId& ...
- html中设置一个div可编辑文本
<div contenteditable="true"></div> <!-- outline: none;设置获取焦点没有高亮边框 -->