JavaScript中的getOwnPropertyDescriptors方法

来自菜鸟教程
跳转至:导航、​搜索

ECMAScript 2017 规范中用于 JavaScript 的新功能之一是 getOwnPropertyDescriptors 方法。 简而言之,此方法返回给定对象的所有属性的信息,包括有关 getter 和 setter 的信息。 它允许我们创建对象的副本并在复制所有属性(包括 getter 和 setter)时克隆它。

在 JavaScript 中,我们可以创建特殊的属性,这些属性在对象内部表现为方法,在对象外部表现为属性。 它们被称为 getset

// object with get and set properties

const gator = {
  name: 'Ben',
  type: 'reptilian',
  get fullName(){
    return `${this.name}${this.type}`;
  },
  set gatorName(name){
    this.name = name;
  }
};  

如果我们执行 console.log(gator) 我们将只得到名称和类型。 然而,我们仍然可以访问 getter fullName,尽管它在控制台中不可见。

console.log(gator)      // {name: 'Ben',  type: 'reptilian',}
console.log(gator.fullName) // 'Benreptilian'

请注意,我们将 getter 称为普通属性,而不是方法。


克隆对象

我们使用 Object.assign() 在 javaScript 中克隆对象。 如果您不熟悉 Object.assign 方法,请阅读 文章,了解如何在 JavaScript 中管理对象。 这种方法的主要问题是当我们克隆对象时,结果并不完全符合我们的预期。 该方法不适用于 getter 和 setter。

const cayman = {Object.assign({}, gator};
console.log(cayman)         // {name: 'Ben',  type: 'reptilian', fullName: Benreptilian, gatorName: undefined }

因此,getter 和 setter 成为常用值。 如果 getter 是一个计数器值,则 setter 将是未定义的。

让我们用 getOwnPropertyDescriptors 方法来克隆对象。

const crocodilian = Object.defineProperties({}, Object.getOwnPropertyDescriptors(gator)));

现在让我们比较一下我们拥有的每个对象的描述符:

console.log(Object.getOwnPropertyDescriptors(gator));

/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
    fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
    gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},        
*/

console.log(Object.getOwnPropertyDescriptors(cayman));

/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
    fullName: {value: 'Benreptilian', writable: true, enumerable: '', configurable: ''},
    gatorName: {value: undefined, writable: true, enumerable: '', configurable: ''},        
*/

console.log(Object.getOwnPropertyDescriptors(crocodilian));

/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
    fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
    gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},        

*/

gator 的对象属性 nametype 被定义为通常的属性,但 fullName 和 gatorName 被定义为 getter 和 setter。 它们没有 value 字段,但有 getset 字段。 cayman 的对象 getter 和 setter 现在被描述为通常的值。 通过 crocodilian 对象,我们设法保存了它的 getter 和 setter,这要归功于 getOwnPropertyDescriptors

getOwnPropertyDescriptors 方法有助于避免数据丢失,使用它我们可以创建对象的深层副本,而无需依赖其他实用程序函数。