前言
在前端面试中,对 JavaScript 的对象考察有很多种。比如对象传参是按引用传递还是按值传递;比如对象的 key 如果不是字符串该如何解析;比如对象连续赋值等等问题。今天通过以下几道笔试题来考察对象的这些特点。
试题1
function changeObjProperty(o) {
o.siteUrl = "http://www.baidu.com"
o = new Object();
o.siteUrl = "http://www.google.com";
o.name = 456
}
let webSite = new Object();
webSite.name = '123';
changeObjProperty(webSite);
console.log(webSite); // {name: 123, siteUrl: 'http://www.baidu.com'}
解析:
该题的输出结果为 {name: 123, siteUrl: 'http://www.baidu.com'}
。对象作为参数传递时是按引用传递的。在 changeObjProperty 函数内,o 又被指向了一个新的地址(new Object()),所以后面的 o.siteUrl = "http://www.google.com";
是新地址对象的属性,不会覆盖旧地址的属性。
试题2
- 对象 key 为数值类型
var a={}, b='123', c=123;
a[b]='b';
a[c]='c';
console.log(a[b]);
解析:
输出结果为 c。如果对象的 key 不是字符串,会隐式地用 toString 方法转换成字符串。所以 a[c] = ‘c’
实际上也是 {"123":"c"}
,覆盖了前面的 {"123":"b"}
- 对象 key 为 Symbol 类型
var a={}, b=Symbol('123'), c=Symbol('123');
a[b]='b';
a[c]='c';
console.log(a[b]);
解析:
输出结果为 b。如果对象的 key 是 Symbol 类型,即便 Symbol 参数中的值一样,对象的 key 也不一样。这也是 Symbol 类型最重要的特征和应用。所以变量 b 和 变量 c 不是相同的 key,后者 key 值也不会覆盖前者。
- 对象 key 为引用类型
var a={}, b={key:'123'}, c={key:'456'};
a[b]='b';
a[c]='c';
console.log(a[b]);
解析:
输出结果为 c。上面也有提到,如果对象的 key 是 不是字符串类型,会通过 toString 方法转换为字符串。很显然变量 b 和 变量 c 皆为对象。他们都会被转换为 “[object Object]” 字符串。因此后者 key 值会覆盖前者。
试题3
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x)
console.log(b.x)
解析:
- a.x 输出为
undefined
。连续赋值是按从右到左的顺序。当赋值a = {n: 2}
的时候,并无 x 属性。并且 . 的操作符运算比 = 要高。所以执行a.x
时结果为undefined
。 - b.x 输出为
{n:2}
。以上案例中继续执行a.x = {n:2}
。而 b 是 a 的引用。所以b.x
为{n:2}
。
持续更新中…