Object.create第二参数通过属性描述符精确控制新对象属性行为,支持value/writable/enumerable/configurable及getter/setter,可实现只读继承、混合数据与访问器属性等受控继承结构。

Object.create 的第二参数允许你精确控制新对象上每个属性的行为,比如是否可写、是否可枚举、是否可配置,还能指定 getter/setter。这比直接赋值或简单原型继承更精细,适合构建受控的继承结构。
第二参数的语法结构
第二参数是一个属性描述符对象,键是属性名,值是该属性的描述符(descriptor),格式如下:
- value:属性的初始值(与 writable 配合)
- writable:是否可修改(true/false)
- enumerable:是否可在 for...in 或 Object.keys() 中出现
- configurable:是否可被 delete、是否可修改描述符本身
- get / set:定义访问器属性(不能与 value/writable 同时使用)
用 Object.create 实现只读继承属性
假设你想让子对象继承父对象某个属性,但禁止子对象修改它(即使子对象自身没定义同名属性):
const parent = { name: 'Base' };
const child = Object.create(parent, {
name: {
value: 'Child',
writable: false,
enumerable: true,
configurable: false
}
});
console.log(child.name); // 'Child'
child.name = 'New'; // 无效(严格模式下报错)
注意:这里 name 是 child 自身属性,遮蔽了原型上的 name;若想继承并锁定原型上的值,应省略 value,改用 getter:
const child = Object.create(parent, {
name: {
get() { return this.__proto__.name; },
enumerable: true,
configurable: false
}
});
混合数据属性与访问器属性的继承控制
常见场景:继承一个“只读 ID”,同时添加一个可写的“status”字段:
const base = { id: Symbol('base') };
const instance = Object.create(base, {
id: {
get() { return this.__proto__.id; },
enumerable: true
},
status: {
value: 'pending',
writable: true,
enumerable: true,
configurable: true
}
});
console.log(instance.id); // Symbol('base')
instance.status = 'done'; // ✅ 允许
delete instance.status; // ✅ 允许(configurable: true)
delete instance.id; // ❌ 不允许(默认 configurable: false,且无显式设置)
避免常见陷阱
- 不要混用 value 和 get/set —— 会抛出 TypeError
- 不传第二参数时,Object.create(obj) 创建的对象自身无属性,所有访问都走原型链
- 如果只想继承、不添加新属性,第二参数传空对象 {} 即可(此时新对象自身无属性,但可定义后续属性)
- 描述符中未声明的字段(如没写 enumerable)默认为 false,这点和 Object.defineProperty 不同(后者未声明字段默认为 false,但 Object.create 的第二参数里所有字段都必须显式设置)

















