JavaScript 中的 getOwnPropertyDescriptors 方法

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

在JavaScript中,我们可以创建特殊的属性,它们作为对象内部的方法行为,并作为对象外部的属性行为,它们被称为得到设置

 1// object with get and set properties
 2
 3const gator = {
 4  name: 'Ben',
 5  type: 'reptilian',
 6  get fullName(){
 7    return `${this.name}${this.type}`;
 8  },
 9  set gatorName(name){
10    this.name = name;
11  }
12};

如果我们做‘console.log(gator)’,我们只会得到名称和类型,然而,我们仍然可以访问 fullName 接口,尽管它在控制台上看不见。

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

<$>[注] 请注意,我们将getter称为通常的属性,而不是方法。

克隆物体

我们使用Object.assign()来克隆JavaScript中的对象. 如果您不熟悉Object.assign方法,请阅读JavaScript中的《如何管理对象》(https://andsky.com/tech/tutorials/js-dealing-with-objects)文章。 这种方法的主要问题是,当我们克隆对象时,结果并不完全如我们所期望的那样。

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

因此,getter 和 setter 成为常见值,如果 getter 是对比值,则 setter 将是未定义的。

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

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

现在让我们比较我们所拥有的每个对象的描述器:

 1console.log(Object.getOwnPropertyDescriptors(gator));
 2
 3/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
 4    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
 5    fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
 6    gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},        
 7*/
 8
 9console.log(Object.getOwnPropertyDescriptors(cayman));
10
11/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
12    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
13    fullName: {value: 'Benreptilian', writable: true, enumerable: '', configurable: ''},
14    gatorName: {value: undefined, writable: true, enumerable: '', configurable: ''},        
15*/
16
17console.log(Object.getOwnPropertyDescriptors(crocodilian));
18
19/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
20    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
21    fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
22    gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},        
23
24*/

gator的对象属性nametype被定义为常规属性,但 fullName 和 gatorName 被定义为 getter 和 setter. 它们没有字段,但有getset字段. cayman的对象 getter 和 setter现在被描述为常规值。

getOwnPropertyDescriptors方法有助于避免数据丢失,通过它,我们可以创建对象的深度副本,而不依赖另一个实用功能。

Published At
Categories with 技术
Tagged with
comments powered by Disqus