MST

星途 面试题库

面试题:JavaScript原型链中的复杂特性分析

在JavaScript中,`Object.create(null)`创建的对象与普通对象在原型链上有何不同?这种不同会对对象的属性查找、遍历以及使用`for...in`等操作产生怎样的影响?请详细阐述并通过代码示例说明。
21.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 原型链的不同

    • 普通对象(如通过{}new Object()创建)的原型是Object.prototype。可以通过obj.__proto__ === Object.prototype验证。
    • 使用Object.create(null)创建的对象没有原型,即obj.__proto__ === null
  2. 对属性查找的影响

    • 普通对象:当查找对象属性时,如果对象本身没有该属性,会沿着原型链向上查找,直到找到该属性或到达原型链顶端(Object.prototypeObject.prototype__proto__null)。例如:
const normalObj = {};
normalObj.a = 1;
console.log(normalObj.a); // 1
// 查找toString属性,对象本身没有,从原型链上查找
console.log(normalObj.toString); // [Function: toString]
  • Object.create(null)创建的对象:由于没有原型链,仅在对象自身查找属性。如果对象本身没有该属性,则返回undefined。例如:
const objFromNull = Object.create(null);
objFromNull.a = 1;
console.log(objFromNull.a); // 1
// 查找toString属性,对象本身没有,且没有原型链可查,返回undefined
console.log(objFromNull.toString); // undefined
  1. 对遍历及for...in操作的影响
    • 普通对象for...in循环不仅会遍历对象自身的可枚举属性,还会遍历原型链上的可枚举属性。例如:
const normalObj = {};
normalObj.a = 1;
Object.prototype.b = 2;
for (let key in normalObj) {
    console.log(key); // 输出 'a' 和 'b'
}
  • Object.create(null)创建的对象:因为没有原型链,for...in仅遍历对象自身的可枚举属性。例如:
const objFromNull = Object.create(null);
objFromNull.a = 1;
Object.prototype.b = 2;
for (let key in objFromNull) {
    console.log(key); // 仅输出 'a'
}

总结来说,Object.create(null)创建的对象在原型链、属性查找和遍历方面与普通对象有明显不同,这种特性在需要完全独立且避免原型链干扰的场景下很有用,比如实现一些特殊的数据结构。