ECMAScript 之 for...in 與 class 研究
栏目: JavaScript · 发布时间: 7年前
内容简介:若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 研究面临哪些“天花板”?未来的重点研究方向又在哪?
- 中国电信广州研究院与思博伦通信共同推动智能化承载网络测试技术研究
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
iOS游戏编程之从零开始
李华明 / 2013-2 / 59.00元
《iOS游戏编程之从零开始:Cocos2d-x与cocos2d引擎游戏开发》是作者继《android游戏编程之从零开始》热销之后编写的又一本、基于cocos2d—x2.x和cocos2d—iphone版本,讲述ios平台游戏开发的新作。《iOS游戏编程之从零开始:Cocos2d-x与cocos2d引擎游戏开发》分为两个部分共11章,内容主要包括cocos2d—x引擎游戏开发的基础,常用的类、方法及......一起来看看 《iOS游戏编程之从零开始》 这本书的介绍吧!