JavaScript 中遍歷對象的屬性

原文連接

JavaScript 中遍歷對象的屬性html

參考

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

相關文章
相關標籤/搜索