为何JavaScript扩展运算符保留设为undefined的键?与未定义键有何区别?
JavaScript中显式赋值为undefined的属性与未定义属性的差异
在JavaScript里,对象中显式赋值为undefined的属性和从未定义过的属性常被开发者混淆——毕竟访问二者时typeof结果都是undefined,而且JSON.stringify都会忽略它们,但这两者本质上完全不同,最直观的差异就体现在扩展运算符的行为上。
核心本质区别
- 显式赋值为undefined的属性:属于对象的可枚举自有属性,实实在在存在于对象的属性集合中,只是值为
undefined。 - 未定义的属性:完全不存在于对象中,访问时返回
undefined仅仅是JavaScript的默认行为,该属性从未被添加到对象里。
代码示例分析
先看你提供的代码运行结果(补充注释):
const obj1 = {a: "apple", c:"crab", d:"dagger", e: undefined}; const obj2 = {a: "aardvark", b:"blue", c: undefined, f: "flamethrower", g: undefined}; const res1 = { ...obj1, ...obj2 }; // res1结果:{a: "aardvark", c: undefined, d: "dagger", e: undefined, b: "blue", f: "flamethrower", g: undefined} // 原因:扩展运算符遍历对象所有可枚举自有属性,obj2的c: undefined覆盖obj1的c: "crab",同时obj2的b、f、g(含值为undefined的g)都被合并 const res2 = { ...obj2, ...obj1 }; // res2结果:{a: "apple", b: "blue", c: "crab", f: "flamethrower", g: undefined, d: "dagger", e: undefined} // 原因:obj1的c: "crab"覆盖obj2的c: undefined,obj1的d、e(值为undefined)被合并进来 const res3 = { ...obj1 }; // res3结果:{a: "apple", c: "crab", d: "dagger", e: undefined} // 原因:obj1的e是显式定义的属性,扩展运算符会保留它;h从未定义,所以res3中没有h属性 console.log(res1); console.log('===='); console.log(res2); console.log('===='); console.log(res3); console.log('===='); console.log(typeof res3.e); // undefined(属性存在,值为undefined) console.log(typeof res3.h); // undefined(属性不存在,访问返回默认undefined) console.log(JSON.stringify(obj1)); // {"a":"apple","c":"crab","d":"dagger"}(JSON.stringify忽略值为undefined的属性)
其他场景的差异表现
除了扩展运算符,这两种属性在很多API中的行为都不一样:
- 对象遍历:
for...in、Object.keys()、Object.getOwnPropertyNames()都会遍历到显式赋值为undefined的属性,但不会处理未定义的属性。 - 属性存在性检查:
obj.hasOwnProperty('e')对显式undefined的属性返回true,对未定义的属性返回false。 - 解构赋值:解构显式
undefined的属性会得到undefined;解构未定义的属性时,如果设置了默认值,会使用默认值,否则才返回undefined:const { e = 'default', h = 'default' } = obj1; console.log(e); // undefined(属性存在,值为undefined) console.log(h); // 'default'(属性不存在,使用默认值) - Object.assign():和扩展运算符逻辑一致,会复制显式
undefined的属性,不会处理未定义的属性。
总结
别再把“显式设置属性值为undefined”和“未定义属性”混为一谈——前者是存在但值为undefined,后者是根本不存在。不同的JavaScript API会根据这个本质差异做出不同处理,记住这一点就能避免很多类似的坑。
内容的提问来源于stack exchange,提问作者Summitch
相关产品推荐
相关产品推荐

