持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
目录
今日题
题目
var p1 = {name: '鲨鱼辣椒'}
var p2 = p1
var process = function (o) {
o = {name: '蜻蜓队长'}
}
process(p2)
console.log(p2.name)
分析
昨天大概讲了基本数据类型与引用数据类型之间的关系,基本数据类型是将变量的值存在栈中,引用数据类型是将变量的内存地址值存在栈中,严谨点来说var a = 1; var b = a;
相当于把a的值(这个值有可能是基本数据类型的值,也有可能是引用数据类型的值)拷贝一份给b,此时拷贝后的b与a是完全相等的。引用数据类型是通过内存地址值去堆内存中找到对应的数据从而返回,若两个变量a、b都指向同一个对象(object),通过一个变量a修改对象中的内容,另一个变量b看到的是修改之后的内容,若其中一个变量a指向了新的对象,则修改变量a中的内容,变量b看到的还是修改之前的内容。
昨日题
题目
var a = {b: 1}
var b = {a: 2}
var obj = typeof (c)
obj++
if (obj == NaN) {
obj[a] = 3
}
obj[b] = 4
console.log(obj[a])
答案
undefined
解析
老规矩,我们先来看一看整体代码,可能会让人有点摸不到头脑,先是a对象中套了个b属性,又是b对象中套了个a属性,甚至更奇怪的是obj中居然还把a、b两个对象作为属性直接进行赋值了,好家伙,这操作我真的悟了。下面我们开始分析主要代码,首先typeof(c)
会返回'undefined'
,这是因为typeof
在判断未声明的变量时会返回'undefined'
,需要注意的是这个'undefined'
是字符串类型,并不是undefined
类型。随后执行obj++,可以看成obj = obj + 1
,因为++运算符是将原值加1,所以先对obj求值,调用obj的valueof
方法,返回结果为NaN
,if中的判断条件NaN == NaN
,而NaN与NaN是不可能相等的,所以会返回false
,随后执行obj[b] = 4
,这里的b会进行隐式类型转换,即调用b的toString方法得到'[object object]'
,所以该语句实际上相当于obj['object object'] = 4
,本质上就是给obj添加属性,但是我们要注意obj是基本数据类型,而基本数据类型由于包装类的加持,所以往往在一个基本数据类型身上添加属性时,虽然会添加成功但是却访问不到,这里无论是obj[a]
还是obj[b]
我们都可以将其直接忽略掉,所以打印obj[a]
会返回undefined
。但如果将题目中的var obj = typeof(c)
替换为var obj = new String('hello')
,那么输出结果又会是另一种情况了(同时需要删除obj++,因为这会影响到我们的数据类型)。
结语
此文章已收录至《JavaScript每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。创作不易,少年,就请留个赞再走吧!