问题描述
在 MDN doc 我无法理解关于 Object.defineProperty descriptor
的这部分:
请记住,这些属性不一定是 描述符自身的属性。将考虑继承的属性 以及。为了确保保留这些默认值,您可以 预先冻结 Object.prototype,明确指定所有选项, 或使用 Object.create(null) 指向 null。
如果我不保留描述符属性会怎样? 有没有可能发生意想不到的事情?举个例子好吗?
解决方法
这是一个非常特殊的建议 IMO,仅用于非常防御性的代码。举个例子:
您可以预先冻结 Object.prototype,明确指定所有选项,或者使用 Object.create(null) 指向 null。
如果你不这样做,那么如果你碰巧有代码发生了变异Object.prototype
(你真的不应该,在任何理智的情况下),和变异的 { {1}} 添加描述符使用的属性,即使它们不直接位于对象上,也会使用这些属性。像这样:
Object.prototype
一个可能的补救方法是提前冻结 // FOR INFORMATIONAL USE ONLY
// NEVER USE THIS NEXT LINE IN REAL CODE
Object.prototype.writable = true;
// then later:
const obj = {};
Object.defineProperty(obj,'prop',{ value: 'value' });
/* In normal circumstances,the resulting descriptor would be:
{
value: 'value',enumerable: false,writable: false,configurable: false,}
But because `writable` was inherited from Object.prototype is true,the property is writable:
*/
obj.prop = 'value2';
console.log(obj.prop);
,这样就不可能发生这样的突变:
Object.prototype
或者确保创建的描述符对象不是从 'use strict'; // so error below is explicit
Object.freeze(Object.prototype);
// FOR INFORMATIONAL USE ONLY
// NEVER USE THIS NEXT LINE IN REAL CODE
Object.prototype.writable = true;
继承的:
Object.prototype
或者明确写出描述符的所有值,而不依赖于默认值:
// FOR INFORMATIONAL USE ONLY
// NEVER USE THIS NEXT LINE IN REAL CODE
Object.prototype.writable = true;
// then later:
const obj = {};
const descriptor = Object.create(null);
descriptor.value = 'value';
Object.defineProperty(obj,descriptor);
obj.prop = 'value2';
console.log(obj.prop);
但在任何远程健全的代码中,这些都不是必需的,因为 // FOR INFORMATIONAL USE ONLY
// NEVER USE THIS NEXT LINE IN REAL CODE
Object.prototype.writable = true;
// then later:
const obj = {};
Object.defineProperty(obj,{
value: 'value',});
obj.prop = 'value2';
console.log(obj.prop);
不应该从一开始就发生变异。