【JavaScript】【對象】屬性和方法的總結概括

構造函數、原型對象、實例對象之間的關係錯綜複雜,關於它們的屬性和方法不少,長得也很像。這裏概括出來,方便記憶和查閱。segmentfault

對象屬性類型

數據屬性

[[Configurable]]:表示可否經過delete刪除屬性從而從新定義屬性、可否修改屬性的特性、可否把屬性修改成訪問器屬性。默認值爲true
[[Enumerable]]:表示是否可枚舉。默認值爲true
[[Writable]]:表示可否修改屬性的值。默認值爲true
[[Value]]:包含屬性的數據值,在這裏讀寫屬性。默認值爲undefined數組

修改屬性的特性:Object.defineProperty()Object.defineProperties()。調用這兩個方法時,若是不指定,configurableenumerablewritable特性的默認值都是false函數

//定義一個屬性
var person = {};
Object.defineProperty(person, 'name', {
    value: 'hiyohoo',
    configurable: true,
    enumerable: true,
    writable: true
});

//定義多個屬性
var person = {};
Object.defineProperties(person, {
    name: {
        value: 'hiyohoo'
    },
    age: {
        value: 24,
        configurable: true,
        writable: true
    }
});

獲取屬性的特性:Object.getOwnPropertyDescriptor()只能用於實例屬性,要取得原型屬性的描述符,須要在原型上使用該方法。this

var descriptor = Object.getOwnPropertyDescriptor(person, 'age');
alert(descriptor.writable);    //true

訪問器屬性

[[Configurable]]
[[Enumerable]]
[[Get]]:讀取屬性時調用該函數。默認值爲undefined
[[Set]]:寫入屬性時調用該函數。默認值爲undefinedprototype

訪問器屬性不能直接定義,必須使用Object.defineProperty()來定義。訪問器屬性經常使用於改變該屬性,其餘屬性也會變化的狀況。code

var book = {
    _year: 2004,    //屬性前面的下劃線記號經常使用於表示只能經過對象方法訪問的屬性。
    edition: 1
};
Object.defineProperty(book, 'year', {
    get: function() {
        return this._year;
    },
    set: function(newValue) {
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2016;
console.log(book.edition);    //13

屬性和方法

如下的屬性和方法均如下面的代碼爲例:對象

var Person = function(name) {
    this.name = name;
};
Person.prototype.school = 'HNU';
Person.prototype.sayName = function() {
    return this.name;
};

var person = new Person('hiyohoo');

構造函數

prototype指向原型對象,包含全部被實例共享的屬性和方法。繼承

console.log(Person.prototype);    //Person{}

原型對象

constructor指向構造函數。ip

console.log(Person.prototype.constructor === Person);    //true

isPrototypeOf()判斷實例與原型之間的關係。原型鏈

console.log(Person.prototype.isPrototypeOf(person));    //true

實例對象

constructor沿着原型鏈找到原型中的constructor屬性,最終指向構造函數。

console.log(person.constructor === Person);    //true

__proto__Firefox、Safari、Chrome支持這個屬性,指向原型對象。

console.log(person.__proto__ === Person.prototype);    //true

hasOwnProperty()Object中繼承而來,判斷屬性是不是實例的私有屬性,而不是繼承而來的共享屬性。

console.log(person.hasOwnProperty('name'));    //true
console.log(person.hasOwnProperty('school'));    //false

Object

Object.getPrototypeOf() ECMAScript 5中新增的方法,返回實例的原型。

console.log(Object.getPrototypeOf(person));    //Person{}

Object.keys() ECMAScript 5中新增的方法,返回一個包含全部可枚舉實例屬性的字符串數組。

console.log(Object.keys(person));    //["name"]
console.log(Object.keys(Person.prototype));    //["school", "sayName"]

Object.getOwnPropertyNames()返回全部實例屬性,不管是否可枚舉。

console.log(Object.getOwnPropertyNames(person));    //["name"]
console.log(Object.getOwnPropertyNames(Person.prototype));    //["constructor", "school", "sayName"]

操做符

delete刪除一個configurabletrue的私有屬性。

delete person.name;
delete person.school;

console.log(person.name);    //undefined
console.log(person.school);    //HNU

for-in返回全部可以訪問到的屬性。

for (p in person) {
    console.log(p);    //name school sayName
}

in對象可以訪問到屬性時返回true

console.log('name' in person);    //true
console.log('sayName' in person);    //true
console.log('age' in person);    //false

同時使用hasOwnProperty()方法和in操做符,能夠肯定一個屬性是存在於對象中仍是存在於原型中。

function isPrototypeProperty(object, name) {
    if (!(name in object)) {
        return ("Can't find " + '"' + name + '"');
    } else if (object.hasOwnProperty(name)) {
        return false;
    } else {
        return true;
    }
}

console.log(isPrototypeProperty(person, 'name'));    //false
console.log(isPrototypeProperty(person, 'school'));    //true
console.log(isPrototypeProperty(person, 'age'));    //Can't find "age"

instanceof用於判斷一個對象是不是某個對象的實例。

console.log(person instanceof Person);    //true
console.log(person instanceof Object);    //true

轉載請註明出處:http://www.javashuo.com/article/p-mvigwoal-bh.html

文章不按期更新完善,若是能對你有一點點啓發,我將不勝榮幸。

相關文章
相關標籤/搜索