刷视频看到了一个面试题,感觉比较考验基础知识
题目如下
// 代码输出结果是什么
const obj = {
a: 0,
};
obj['1'] = 0;
obj[++obj.a] = obj.a++;
const values = Object.values(obj);
obj[values[1]] = obj.a;
console.log(obj);
我们一行一行的进行解释
第2-4行没啥好说的,就是声明一个对象
第5行
对象的属性名只有两种类型:字符串和symbol
如果属性名是其他数据类型,也会自动转变为字符串
对象中属性分为排序属性和普通属性
普通属性
普通字符串,比如字母或单词,他是按照添加的顺序排列
排序属性
数字,一些标点符号,按照升序排列
由此可以得知 obj['1'] 和 obj[1] 其实是同一个属性,如图:
let obj = {a:1};
obj[1] = 10;
obj['1'] = 20;
obj[{}] = 100;
obj
{1: 20, a: 1, [object Object]: 100}//输出得到
从输出的内容还能看出一些奇怪的地方,明明 属性a 是先在对象中的,但是输出时 属性'1' 却在前面
这就是上述的 排序属性 的作用,排序属性会按照升序放在对象最前面,然后接着是普通属性
所以第5行相当于给obj增加了一个值为0的属性1
第6行
用到++前后使用的情况
++在前,就是先返回计算结果
++在后,就是先给当前结果,再进行计算
++obj.a 属于先计算,所以这里是 obj[1]
obj.a 修改为了 1
obj.a++ 属于先给结果,后计算,这里是返回 1
obj.a 修改为 2
所以第6行结果是: obj[1] = 1;obj.a = 2;
第7行
这一行属于正常 Object.values 获取 obj 的值数组,复制给 values
Object.values()
静态方法返回一个给定对象的自有可枚举字符串键属性值组成的数组。
第8行
获取数组的第二个元素
需要注意前面提到的 排序属性 ,数字在前,字母在后,所以 values[1] 的值是 属性 a 的值,也就是 2
结果如下:
obj[2] = obj.a;
//也就是obj[2] = 2;
第9行
就是普通输出,我们先来整理一下对象 obj 的内容,应该是这样的:
{
1:0,//line5的效果
1:1,//line6的效果
a:2,//line6的效果
2:2,//line8的效果
}
然后最终结果为(注意排序属性的影响)
{
1:1,
2:2,
a:2
}
所以输出就是
{1:1,2:2,a:2}