JavaScript中的屬性:如何遍歷屬性
《JavaScript 高級程序設計》數組
遍歷 JavaScript 對象中的屬性沒有其餘語言那麼簡單,由於兩個因素會影響屬性的遍歷:對象屬性的屬性描述符 (property descriptor) 的 [[Enumerable]]
特性爲 true
(可枚舉)才能被 for-in
訪問;若是在對象自己沒有找到屬性,接下來會在原型鏈上查找,訪問屬性時會沿着整個原型鏈從下到上查找屬性。因此說遍歷屬性時,要考慮這兩個因素。oop
先定義兩個類吧:Person 和 Student,後者繼承前者。而後再聲明並初始化一個 Student 的實例 p1。其中自身屬性有 grade(可枚舉) 和 tel(不可枚舉),從原型鏈繼承屬性 type.
可枚舉意思是屬性的 [[Enumerable]]
值爲 true
,自身的屬性意思是 不是 從 原型鏈 繼承的屬性this
// ES3 ES5 function Person(name) { this.name = name; } Person.prototype.type = 'people'; function Student(name, grade) { Person.call(this, name); this.grade = grade; } if (Object.setPrototypeOf) { Object.setPrototypeOf(Student.prototype, Person.prototype); } else { Student.prototype = Object.create(Person.prototype); Object.defineProperty(Student.prototype, 'constructor', { enumerable: false, writable: true, configurable: true, value: Student }); } var p1 = new Student('Zero', 'Junior'); Object.defineProperty(p1, 'tel', { value: 123456, enumerable: false });
// ES6+ class Person { constructor(name) { this.name = name; } } Person.prototype.type = 'people'; class Student extends Person { constructor(name, grade) { super(name); this.grade = grade; } } var p1 = new Student('zero', 'Junior'); Object.defineProperty(p1, 'tel', { value: 123456, enumerable: false });
使用 Object.keys()
或是 for..in
+ hasOwnProperty()
prototype
// Object.keys()返回可枚舉、自身的屬性 // 再用for..of對返回的數組進行遍歷 for (let prop of Object.keys(p1)){ console.log(prop); }
// 獲得可枚舉、自身+繼承的屬性 for (let prop in p1) { // 過濾繼承屬性 if (p1.hasOwnProperty(prop)) { console.log(prop); } }
結果是:name 和 grade 屬性
注: Object.keys()
的使用環境是 ES5+設計
// 使用 `Object.getOwnPropertyNames()` for (let prop of Object.getOwnPropertyNames(p1)) { console.log(prop); }
結果是:name 、 grade 和 tel 屬性code
// 使用 `for..in` for (let prop in p1) { console.log(prop); }
結果是:name 、 grade 和 type 屬性htm
var getAllPropertyNames = (obj) => { var props = []; do { props = props.concat(Object.getOwnPropertyNames(obj)); } while (obj = Object.getPrototypeOf(obj)); return props; }; for (let prop of getAllPropertyNames(p1)) { console.log(prop); }
結果不少:包括自身屬性 name 、 grade 等,繼承屬性 type 、 toString 、valueOf 等對象
EOFblog