ECMAScript 之 for...in 與 class 研究
栏目: JavaScript · 发布时间: 6年前
内容简介:若ECMAScript 2015
Object.keys()
與 for...in
的差異在於 Object.keys()
只能顯示目前 Object 的 Property Key,而 for...in
會連同 Prototype 的 Property Key 一併顯示。
若 for...in
搭配 Constructor Function 或 Object.create()
時一切正常,但搭配 class
時,就無法顯示 Prototype 的 Property Key 了,為什麼會這樣呢 ?
Version
ECMAScript 2015
Constructor Function
function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } Person.prototype.fullName = function() { return this.firstName + ' ' + this.lastName; }; const person = new Person('Sam', 'Xiao'); for(let key in person) console.log(key); // firstName // lastName // fullName
由 Constructor Function 建立 object,並將 method 定義在 Prototype,這是 ECMAScript OOP 標準寫法。
當對 object 使用 for...in
,會顯示所有的 Property Key,連 Prototype 也會顯示。
fullName() for...in fullName
Object.create
const prototype = { fullName: function() { return this.firstName + ' ' + this.lastName; }, }; const person = Object.create(prototype); person.firstName = 'Sam'; person.lastName = 'Xiao'; for(let key in person) console.log(key); // firstName // lastName // fullName
Prototype 除了事後在 Constructor Function 動態指定外,也可以事先建立 Prototype object,然後傳入 Object.create()
。
一樣使用 for...in
,也如預期列出 Prototype 的 Property Key。
Object.create() for...in fullName
Class
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } fullName() { return this.firstName + ' ' + this.lastName; } } const person = new Person('Sam', 'Xiao'); for(let key in person) console.log(key); // firstName // lastName
ECMAScript 2015 導入 class
語法後,method 可以直接定義在 class 內,會自己幫我們定義在 Prototype。
但使用 for..in
,卻發現 Prototype 的 fullName
無法顯示,退化成與 Object.keys()
功能一樣,為什麼會這樣呢 ?
for...in fullName
Why ?
for...in
與 Object.keys()
都僅能列出 Enumerable Property,所以很有可能 class
的寫法,造成 Prototype 的 property 為 Non Enumerable Property,造成 for...in
無法顯示。
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } fullName() { return this.firstName + ' ' + this.lastName; } } const person = new Person('Sam', 'Xiao'); console.log(Object.getOwnPropertyDescriptor(person, 'firstName')); console.log(Object.getOwnPropertyDescriptor(person, 'lastName')); console.log(Object.getOwnPropertyDescriptor(person.__proto__, 'fullName')); for(let key in person) console.log(key);
Object.getOwnPropertyDescriptor()
會傳回每個 property 的屬性,藉此觀察是否為 Non Enumerable。
- 特別加上
Object.getOwnPropertyDescriptor()
觀察之 - 果然如假設所言,Prototype 的
fullName
其enumerable
為false
,因此for...in
無法顯示
'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Person = function () { function Person(firstName, lastName) { _classCallCheck(this, Person); this.firstName = firstName; this.lastName = lastName; } _createClass(Person, [{ key: 'fullName', value: function fullName() { return this.firstName + ' ' + this.lastName; } }]); return Person; }(); var person = new Person('Sam', 'Xiao'); for (var key in person) { console.log(key); } //# sourceMappingURL=es6class.js.map
從另外一個角度,我們由 Babel 所 transpile 的 ES5 觀察。
descriptor.enumerable = descriptor.enumerable || false;
對於 Prototype 的 property,Babel 也是將 enumerable
設定為 false
。
由這兩點都可以證明,當使用 class 寫法時,根據 ECMAScript 2015 規格,都會將 Prototype 的 property 設定為 Non Enumerable Property,也就是 for...in
功能將等同 Object.keys()
Conclusion
-
for...in
為 ECMAScript 3 所定義,而Object.keys()
為 ECMAScript 5.1 所加入,理論上兩者的差異就在於 Prototype 部分,但 ECMAScript 2015 支援 class 後,又使得for..in
與Object.keys()
功能趨於一至,個人是不太喜歡這種改變,這使得for...in
與過去的觀念不同,算 breaking change,但既然 ECMAScript 2015 規格就是這樣定義,也只能自己注意這個微小的差異了
以上所述就是小编给大家介绍的《ECMAScript 之 for...in 與 class 研究》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 安全研究 | 传真机的攻击面研究报告
- IBM将建新AI研究中心,旨在开展“颠覆性研究项目”
- 清华人工智能研究院成立「知识智能研究中心」,发布四大知识平台
- 姚班天才少年鬲融凭非凸优化研究成果获得斯隆研究奖
- 大热下的 GNN 研究面临哪些“天花板”?未来的重点研究方向又在哪?
- 中国电信广州研究院与思博伦通信共同推动智能化承载网络测试技术研究
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Netty实战
诺曼·毛瑞尔(Norman Maurer)、马文·艾伦·沃尔夫泰尔(Marvin Allen Wolfthal) / 何品 / 人民邮电出版社 / 2017-5-1 / 69.00
编辑推荐 - Netty之父”Trustin Lee作序推荐 - 阿里巴巴中间件高级技术专家为本书中文版作序推荐 - 系统而详细地介绍了Netty的各个方面并附带了即用型的优质示例 - 附带行业一线公司的案例研究 - 极实用的Netty技术书 无论是构建高性能的Web、游戏服务器、推送系统、RPC框架、消息中间件还是分布式大数据处理引擎,都离不开Nett......一起来看看 《Netty实战》 这本书的介绍吧!