《javascript語言精粹》學習筆記 - 對象

Javascirpt裏的對象是無類型的。它對新屬性的名字和屬性的值沒有任何的限制。對象適用於聚集和管理數據。對象能夠包括其餘對象,因此它們能夠容易地表示成樹狀或者圖形結構。數組

對象字面量

建立一個自定義對象最簡單的方式就是建立一個Object的實例,而後爲它添加屬性和方法:閉包

var person = new Object();
    person.name = 'john';
    person.age = 16;
    person.say = function(){
        console.log(this.name + ' ' + this.age);
    };

後來對象字面量成爲一個建立這種對象的首選方式。對象字面量提供一種很是方便的建立新對象的表示法。函數

var Person = {},
    Person2 = {
        name: 'john',
        age: 16,
        say: function(){
            console.log(this.name + ' ' + this.age);
        }
    };

一個對象字面量就是包圍在一對花括號({})的多個名/值對。對象字面量能夠出現任何容許表達式出現的地方。ui

屬性名能夠包括空字符串在內的任何字符。屬性名是一個合法的js標示符並且不是保留字的話就不用引號括起來。特殊狀況例如:"my-name"這種的話,由於js中的標示符中包含鏈接符(-)是不合法的,因此要用引號去包住,若是用下劃線(_)就不用了。this

對象字面量屬性值裏面能夠在嵌套對象的。prototype

var Person = {
    name: 'john',
    Person2: {
        age: 16
    }
};

檢索

要檢索的對象包含的值,能夠採用[]後綴中括住一個字符串表達式方式。也能夠用.方法,可是前提要是一個合法的js標示符且不是保留字。code

person['name'];
person.name;

若是屬性值沒有的話,咱們能夠用||充當默認值。對象

var name = person['name'] || 'john';

嘗試從undefind對象裏取值將會致使TypEerror異常。能夠經過&&運算符來避免錯誤。繼承

flight.equipment // undefined
flight.equipment.model // TypeError
flight.equipment && flight.equipment.model// undefined

引用

對象是經過引用來傳遞的,而不是複製。ip

// 例子一
var stooge = {},
    x = stooge;
x.nickname = 'john';
var nick = stooge.nickname;
alert(nick); // john

// 例子二
var a = {}, b = {}, c = {};
// a = b = c = {};
  • 例子一的代碼由於xstooge是指向同一個對象的引用。
  • 例子二的代碼其實abc都引用同一個對象。

更新

對象可使用賦值語句來更新值。若是屬性名已經存在的話,就回去被替換掉。若是值不存在,就擴充到對象中。

var person = {
    name: 'Ada'
}
person.name = 'john'; // john
person.age = 16 // 16

原型

每一個對象都能鏈接到一個原型對象,而且它能夠從中繼承屬性。

當你建立一個新的對象的時候,你能夠有選擇性的某個對象做爲它的原型。js給咱們的機制是很複雜的,可是能夠被明顯的簡化,來給Object添加一個create方法。

if (typeof Object.beget !== 'function') {
    Object.create = function(o){
        var F = function(){};
        F.prototype = o;
        return new F;
    };
}
var person = Object.create(person);

注意:原型鏈接在更新時是不會起做用的。當對某個對象作出改變的時候,不會觸及該對象的原型。

原型連接只有在檢索值的時候纔會用到。若是咱們嘗試去獲取對象的某個值的時候,若是對象沒有該屬性名,那麼js會嘗試去原型對象中獲取屬性值。若是那個原型也沒有的話,就會一直從它的原型裏面找。若是最後仍是找不到的話機會返回一個undfined。這個過程稱爲委託

原型關係是一種動態的關係。若是添加到一個新的屬性值到原型中,該屬性會當即對全部基於這個原型建立的對象可見。

反射

檢查對象而且肯定對象有什麼屬性是一件很容易的事情,只要嘗試的去檢索那個屬性而且驗證取得的值。使用typeof來對肯定屬性的類型。

var person = {
    name: 'john',
    age: 16,
    say: function(){
        console.log(this.name + ' - ' + this.age);
    }
};
alert(typeof person.name); // string
alert(typeof person.age); // number
alert(typeof person.say); // function

另一種方法是使用hasOwnProperty方法,若是對象擁有獨有的屬性值,它將會放回true。注意:hasOwnProperty方法不會檢查原型鏈。

alert(person.hasOwnProperty('name')); // true
alert(person.hasOwnProperty('sex')); // false

枚舉

for in循環能夠用來遍歷一個對象中的說有屬性名。
注意:使用for in循環過程當中也會列出那些你不關心的原型中的屬性,若是想要過濾掉那些你不須要的值。你可使用hasOwnProperty方法,以及typeof來排除函數。

for (var name in person) {
    if (typeof person[name] !== 'function') {
        alert(person[name]);
    }
};

屬性名出現的順序是不肯定的,所以要對全部的可能出現的順序有所準備。若是想要確保屬性以特定的順序出現,最好的辦法就是徹底避免使用for in語句,而是建立一個數組,在其中以正確的順序包含屬性名。

var i = 0,
    properties = [
        'name',
        'age'
    ];
for (; i < properties.length; i++) {
    alert(person[properties[i]]);
};

經過使用for循環而不是for in循環,就能夠獲得想要的值,也不用擔憂可能發掘出原型鏈中的屬性。

刪除

delete運算符能夠用來刪除對象的屬性。若是對象包含這個屬性,那麼該屬性就會被移除。亦不會觸及原型鏈中的任何對象。

var Person = function(name, age){
    this.name = name;
    this.age = age;
};
Person.prototype.name = 'Ada';

var person = new Person('john', 16);

alert(person.name); // john
delete person.name;
alert(person.name); // Ada

刪除對象的屬性可能會讓來自原型鏈中的屬性透現出來。

嚴格模式下,不能用delete 刪除顯式聲明的標識符,名稱或具名函數。

減小全局變量污染

js能夠很隨意去定義全局變量來容納你的應用的全部的資源。很差的是,全局變量削弱了程序的靈活性,應該都要避免使用。

最小化使用全局變量的方法之一就是爲你的應用只建立一個惟一的全局變量。

var MyApp = {};

這個變量就會成爲你的應用的容器了。

MyApp.person = {
    name: 'john',
    age: 16
};

MyApp.person2 = {
    name: 'Age',
    age: 14,
    sayName: function(){
        alert('name: ' + this.name);
    }
};

只要把全局性的資源都歸入一個名稱空間下,本身寫的程序與其餘的程序、組件或者類庫之間發生的衝突就會大大的減小。本身寫的程序也會變得更加容易的閱讀。還有另一種方法也是能夠有效的減小全局污染,那就是閉包

相關文章
相關標籤/搜索