這次徹底理解了Object這個屬性

小周sri的碼農發表於2017-09-14

1.例項化Object物件

例項化Object物件的方式有兩種:使用Object構造器和使用物件的字面量。例如:

var person1 = {
    name: '李四'
};

var person2 = new Object();
person2.name = '王二';

2.為實列新增屬性

我們可以隨時隨地為物件新增屬性,也可以隨時修改屬性的值。

var person1 = {
    name: '小明'
};

var person2 = new Object();
person2.name = '小紅';

//給物件新增屬性
person1.age = 23;
person2.age = 25;

//修改屬性的值
person1.name = '張三';
console.log(person1.name);      //'張三'
person2.name = '李四';
console.log(person2.name);      //'李四'

3.刪除物件中的屬性

var person1 = {
    name: '張三'
};

person1.name = null;



console.log(person1.name);      //'張三'

delete person1.name;

console.log(person1.name);      //'undefined'

4.檢查屬性

由於物件的屬性可以被隨時隨地被修改或刪除,因此有時候我們需要檢查物件的某個屬性是否存在。使用下面的方式檢查是不可靠的:

var person1 = {
    name: '張三'
};


person1.name = '';//或者null/undefined

if (person1.name) {

    console.log('存在');

} else {

    console.log('不存在');         //'不存在'
}

使用這種方式可能會得不到正確的結果,如果屬性的值是:物件,非空字串,非零的數或者true,if條件語句會把它們轉換成true。如果屬性的值是:null,undefined,0,false,NaN,空字串,if條件語句會把它們轉換成false。檢差物件中的屬性是否存在的更可靠的方式是使用in操作符:

var person1 = {
            name: '張三'
};


person1.name = '';//或者null/undefined

if ('name' in person1) {

    console.log('存在');          //'存在'

} else {

    console.log('不存在');
}

5.遍歷實列的屬性

預設情況下,我們新增到物件上的屬性都是可列舉的,這樣的話我們就可以使用for-in迴圈遍歷它們。

var obj = {
    name: '王志龍',
    age: 23,
    gender: '男',
    address: '鶴壁'
};

var propertyName;

for (propertyName in obj){

    console.log('屬性名:' + propertyName);
    console.log('屬性值:' + obj[propertyName]);
}

for-in迴圈每迴圈一次都會將一個屬性名賦值給propertyName,直到所有的屬性都被遍歷一遍為止。

如果我們只是想獲取一個物件中的所有屬性名,可以使用Object.keys()方法。該方法會以陣列的形式返回所有的屬性名。

console.log(Object.keys(obj));     // ["name", "age", "gender", "address"]

6.屬性的分類

屬性的型別分兩種:一種是資料屬性,一個種是訪問器屬性。資料屬性用來儲存一個值,比如所上個例子中的name。訪問器屬性不包含值,而是定義了一個getset函式,當讀取屬性時,呼叫get函式,當寫屬性時,呼叫set函式。

下面是一個使用字面量的形式定義訪問器屬性的語法:

var obj = {

    _myname: 'clw',

    get name(){

        console.log('get方法被呼叫了');
        return this._myname + '1111';

    },
    set name(value){

        console.log('set方法被呼叫了');
        this._myname = value;

    }
};

console.log(obj.name);

7.屬性的內部

  7.1共享的屬性:

資料屬性和訪問器屬性共享的內部特性有兩個:一個是[[Enumerable]],這個特性決定了我們是否能夠遍歷該屬性。另一個是[[Configurable]],這個特性決定了我們是否能夠改變屬性。預設情況下我們在物件上新增的屬性都是可列舉、可配置的。

如果我們向改變屬性的特性,可以使用Object.defineProperty()方法。該方法接受3個引數:擁有被修改屬性的物件、被修改的屬性名、包含描述特性的物件。描述符和內部特性名稱相同,但是沒有方括號。例如,我們將一個屬性改成不能列舉,不能配置:

var person1 = {
    name: '張三',
    age: 22
};

console.log(person1.propertyIsEnumerable('name'));

Object.defineProperty(person1, 'name', {
    enumerable: false
});

console.log('name' in person1);                     //true
console.log(person1.propertyIsEnumerable('name'));  //false

var properties = Object.keys(person1);
console.log(properties);                            //["age"]

//delete person1.name;
//console.log(person1.name);                        //'undefined'

Object.defineProperty(person1, 'name', {
    configurable: false
});

delete person1.name;
console.log(person1.name);                          //'張三'

  7.2訪問器屬性內部的特性:

var obj = {

    _myname: 'clw',

    get name(){

        console.log('get方法被呼叫了');
        return this._myname + '1111';

    },
    set name(value){

        console.log('set方法被呼叫了');
        this._myname = value;

    }
};


//上面的程式碼等價於:

var obj2 = {
    _myname: 'clw'
};


Object.defineProperty(obj, 'name', {
    get: function() {

        console.log('get方法被呼叫了');
        return this._myname + '1111';

    },
    set: function(value) {

        console.log('set方法被呼叫了');
        this._myname = value;

    },
    configurable: true,
    enumerable: true
});

  7.3定義多個屬性的內部特性:

定義單個屬性的內部特性使用Object.defineProperty(),定義多個屬性使用的是Object.defineProperties(),這個方法接受2個引數,第一個是屬性所屬的物件,第二個是包含被定義屬性的物件。

  var person1 = {};

        Object.defineProperties(person1, {
            name: {
                value: '張三',
                enumerable: true,
                configurable: true,
                writable: true
            },
            age: {
                value: 23,
                enumerable: false,
                configurable: false,
                writable: false
            },
            address: {
                get: function(){

                },
                set: function(value){

                },
                enumerable: true,
                configurable: true
            }
        });

        console.log(person1.name);              //'張三'
        person1.name = '李四';
        console.log(person1.name);              //'李四'

        console.log(person1.age);               //23
        person1.age = 500;
        console.log(person1.age);               //23

  7.4獲取屬性內部的特性

獲取屬性的內部特性的方法有兩個:Object.getOwnPropertyDescriptor()Object.getOwnPropertyDescriptors()

var person1 = {};

        Object.defineProperties(person1, {
            name: {
                value: '張三',
                enumerable: true,
                configurable: true,
                writable: true
            },
            age: {
                value: 23,
                enumerable: false,
                configurable: false,
                writable: false
            },
            address: {
                get: function(){

                },
                set: function(value){

                },
                enumerable: true,
                configurable: true
            }
        });

        //獲取物件中單個屬性的內部特性
        var descriptor = Object.getOwnPropertyDescriptor(person1, 'address');
        //獲取物件中所有屬性的內部特性
        var descriptors = Object.getOwnPropertyDescriptors(person1);
        console.log(descriptors);

 

相關文章