JS 对象特性面试题

339 阅读3分钟

分享一个js对象的基础面试题,考验Object的一些特性

// 片段1
let a = {name: 'Sam'}
let b = {name: 'Tom'}
const o = {}
o[a] = 1
o[b] = 2
console.log(o[a])

看到这儿,大多数伙计们应该猜到考点是啥了,有疑问的小伙伴可以自行在控制台运行一下结果,看看是否是自己所期待的。 对了答案的意料之外的伙计可以思考一下为什么,也别急着去Google,先在脑子中回忆一下object属性名有哪些特点,咱们接着运行下一段稍微有点差别的代码,看看是否对自己有点启发:

// 片段2
let a = {name: 'Sam'}
let b = {name: 'Tom'}
let c = {name: 'Cat'}
const o = {}
o[a] = 1
o[b] = 2
o[c] = 3
console.log(o[a])

对比下片段1和片段2,打印结果分别是2和3,暂时得到一个结论就是,最终的打印结果是最后一次所赋值,外?回想下Object属性名的特性,那就是最基本的,必须为字符串,或者最终为字符串,到这里我们接着在控制台分别打印a/b/c以及对象o看看:

// 片段3
let a = {name: 'Sam'}
let b = {name: 'Tom'}
let c = {name: 'Cat'}
const o = {}
o[a] = 1
o[b] = 2
o[c] = 3
console.log(o[a])
console.log(o[b])
console.log(o[c])
console.log(o)

结果如下:

image.png

相信到这里很多小伙伴已经恍然大悟了,尤其是看到o的打印,如果不够直观的话可以执行下,Object.keys(o),还有疑问的伙计接着往下,咱们分析下,

  1. 声明对象a,b,c,o值分别为4个不同的对象,o为空对象
  2. 分别将a,b,c的值作为属性名添加o的三个属性,分别赋予三个不同的值

这里我们思考下,对象的属性名必须为字符串,那我们再第二步赋值操作的时候js底层肯定会进行处理,那就是将a,b,c的值转换为字符串作为属性名添加到o,那么最终会转换成什么呢?"{name: 'Sam'}"||"{name: 'Tom'}"||"{name: 'Cat'}"?,答案是否定的,回过头看下我们片段3最后的打印结果:{[object Object]: 3},是否再一次验证自己的推测与Object的特性?

揭晓答案吧!给对象添加属性的时候,会判断属性类型,如果为字符串直接添加,否则会判断属性的类型,如上,并且调用Oject对象原型链上的tostring 方法将之转换为字符串,即 Object.prototype.toString。所以不管添加多少次,只要属性名为对象类型,最终都换转换'[object Object]',因此每一次添加都是改变o['[object Object]']的值,当然打印会以最后一次赋值为准。(插句题外话,Object.prototype.toString用来判断值类型很好用,有兴趣的可以去了解下)

伙计们是不是对Object类型的认识再一次深刻呢,很多题都是针对一些细节基础考察,再立志写出无人能解的bug同时我们也得时刻巩固自己的基础。

🐶富贵,互相旺。。。说错了,积跬步,致千里!