javascript權威指南(6) - 對象

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.prototypeDate.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; // 正常工做
相關文章
相關標籤/搜索