JavaScript對象能夠從一個稱爲原型的對象繼承屬性,這種"原型式繼承"(prototypal inheritance)是JavaScript的核心特徵。除了字符串、數字、true、false、null和undefined以外,JavaScript中的值都是對象。對象時可變的,能夠增長或者刪除對象的屬性,經過引用而非值來操做對象。程序員
對象的常見用法是create對象以及設置(set), 查找(query), 刪除(delete), 檢測(test), 枚舉(enumerate)對象的屬性。web
對象中不能存在同名的屬性,屬性值能夠是任意JavaScript值,或者(ECMAScript5中)能夠是一個getter或setter函數(或者二者都有)。除此以外,每一個屬性還有一些與之相關的值,稱爲"屬性特徵",如可寫(writable)、可枚舉(enumerable)、可配置(configurable)。express
除了包含屬性以外,每一個對象還擁有三個相關的對象特性:數組
對象的原型(prototype):指向另一個對象,本對象的屬性繼承自它的原型對象。
對象的類(class):是一個標識對象類型的字符串。
對象的擴展標記(extensible flag):指明瞭(ECMAScript5中)是否能夠向該對象添加新屬性。ide
三類JavaScript對象和兩類屬性:函數
內置對象(native object): 由ECMAScript規範定義的對象或類。例如Arrays, functions, dates, 和regular expressions。
宿主對象(host object): 由JavaScript解釋器所嵌入的宿主環境(例如web browser)定義的. 如HTMLElement。宿主對象也能夠當作內置對象。
自定義對象(user-defined object): 由運行中的JavaScrip代碼建立的對象。
自有屬性(own property): 直接在對象中定義的屬性。
繼承屬性(inherited property): 在對象的原型對象中定義的屬性。ui
#1 建立對象this
能夠經過對象直接量、關鍵字new和(ECMAScript5中)Object.create()函數來建立對象。spa
對象直接量:prototype
var book = { "main title": "JavaScript", // Property names include spaces, 'sub-title': "The Definitive Guide", // and hyphens, so use string literals "for": "all audiences", // for is a reserved word, so quote author: { // The value of this property is firstname: "David", // itself an object. Note that surname: "Flanagan" // these property names are unquoted. } };
經過對象直接量建立的對象都具備同一個原型對象,並能夠經過JavaScript代碼Object.prototype得到對原型對象的引用。
經過new建立對象(JavaScript語言核心中的原始類型都包含內置構造函數):
var o = new Object(); // Create an empty object: same as {}. var a = new Array(); // Create an empty array: same as []. var d = new Date(); // Create a Date object representing the current time var r = new RegExp("js"); // Create a RegExp object for pattern matching.
經過new關鍵字和構造函數調用建立的對象的原型就是構造函數的prototype屬性的值。如Object.prototype, Array.prototype和Date.prototype等。
Object.create():
var o1 = Object.create({x:1, y:2}); // o1繼承了屬性x和y. var o2 = Object.create(null); // o2不繼承任何屬性和方法,所以不能和"+"運算符一塊兒正常工做 var o3 = Object.create(Object.prototype); // o3和{}或者new Object()同樣.
#2 屬性的查詢和設置
能夠經過點(.)或方括號([])運算符來獲取屬性的值,或者建立屬性和設置屬性。
var author = book.author; // Get the "author" property of the book. var name = author.surname // Get the "surname" property of the author. var title = book["main title"] // Get the "main title" property of the book. book.edition = 6; // Create an "edition" property of book. book["main title"] = "ECMAScript"; // Set the "main title" property.
做爲關聯數組的對象
數組元素經過字符串索引而不是數字索引(如object["property"]),這種數組就是關聯數組,也稱做散列、映射或字典(dictionary)。JavaScript對象都是關聯數組。
function addstock(portfolio, stockname, shares) { portfolio[stockname] = shares; // 使用關聯數組 }
繼承
只有在查詢屬性時纔會體會到繼承的存在,而設置屬性則和繼承無關,這是JavaScript的一個重要特性,讓程序員能夠有選擇的覆蓋(override)繼承的屬性。
var unitcircle = { r:1 }; // 供繼承的對象 var c = inherit(unitcircle); // c 繼承屬性 r c.x = 1; c.y = 1; // c 定義了兩個本身的屬性 c.r = 2; // c 覆蓋其繼承的屬性 unitcircle.r; // => 1: 原型對象不受影響
屬性訪問錯誤
book.subtitle; // => undefined: 屬性不存在 // 拋出一個類型異常錯誤. undefined沒有length屬性 var len = book.subtitle.length; // 一種更簡練的經常使用方法,得到subtitle的length屬性或undefined var len = book && book.subtitle && book.subtitle.length; // 內置構造函數的原型是隻讀的 Object.prototype = 0; // 賦值失敗,但沒有報錯; Object.prototype沒有修改
#3 刪除屬性
delete只是斷開屬性和宿主對象的聯繫,而不會去操做屬性中的屬性;delete預算福只能刪除自有屬性,不能刪除繼承屬性。當delete表達式刪除成功或者沒有任何反作用(好比刪除不存在的屬性)時,返回true。
o = {x:1}; // o有一個屬性x, 並繼承屬性toString delete o.x; // 刪除x, 返回true delete o.x; // 什麼都沒作(x已經不存在了), 返回true delete o.toString; // 什麼都沒作(toString是繼承來的), 返回true delete 1; // 無心義, 返回true
不能刪除那些可配置性爲false的屬性,某些內置對象的屬性是不可配置的,好比經過變量聲明和函數聲明建立的全局對象的屬性。
delete Object.prototype; // 不能刪除,屬性是不可配置的 var x = 1; // 聲明一個全局變量 delete this.x; // 不能刪除這個屬性 function f() {} // 聲明一個全局函數 delete this.f; // 也不能刪除全局函數
在非嚴格模式中刪除全局對象的可配置屬性時,能夠省略對全局對象的引用。
this.x = 1; // 建立一個可配置的全局屬性(沒有用 var) delete x; // 將它刪除
在嚴格模式中會報語法錯誤。
delete x; // 在嚴格模式下報語法錯誤 delete this.x; // 正常工做