JavaScript中的物件學習筆記(概述和建立)

EliotWang發表於2018-06-06

本文是筆者學習JavaScript時做的筆記,大部分內容來自《JavaScript權威指南》,記錄學習中的重點,並引入一些其他博文和與其他程式設計師討論的內容,供本人日常翻閱。如有疑問,請留言評論,對本文的內容想深入瞭解,請支援併購買正版《JavaScript權威指南》。

一. 概述

物件是JavaScript(之後簡稱js)的基本型別之一。以下為Object的一些基本知識(隨時更新)。

  • 其形式是屬性(鍵/值對)的合集,屬性名是字串,可以看做是字串到值的對映合集。

  • 這種基本資料結構也被稱為,雜湊(hash)、雜湊表(hashtable)、字典(dictionary)、關聯陣列(associative array)

  • 物件最重要的特徵是可以從一個被稱為原型的物件那裡繼承屬性,這種原型式繼承(prototypal inheritance)js的核心特徵。

  • 物件是_可變的_,js中宣告一個物件時,是通過引用而不是通過拷貝一個副本,如下所示。

    	 var obj = {
    	 	x:1
    	 };
    	 console.log(obj);
    	 //列印{x:1}
    	 var obj_c = obj;
    	 obj.x = 5;
    	 console.log(obj_c);
    	 //列印{x:5}
    	 obj_c.x = 2;
    	 console.log(obj);
    	 //列印{x:2}
    	 //obj和obj_c實際上對應的是同一個物件引用,因此修改任意一個,都會對物件產生影響。
    	 
    複製程式碼
  • 常用的物件用法(之後會分節討論)

    1. 建立(create)
    2. 設定(set)
    3. 查詢(query)
    4. 刪除(delete)
    5. 檢測(test)
    6. 列舉(enumerate)

二. 屬性的重點

  • 屬性的鍵是包含空字串在內的任意字串,且同一個物件內,不能存在相同的鍵。

  • 屬性可以是任意js支援的值,或者在ES5標準下可以是一個getter和setter的函式(之後會有這兩個函式的討論)。

  • 除了名字和值之外,每個屬性還有一些羽織相關的描述值,稱為屬性特性(property attribute),分別是:

    1. 可寫(writable attribute),表明是否可以設定該屬性的值
    2. 可列舉(enumerable attribute),表明是否可以通過for迴圈遍歷到該屬性
    3. 可配置(configurable attribute),表明是否可以刪除或者修改該屬性。
  • 在es5之前,通過程式碼給物件建立的屬性都是可寫、可列舉和可配置的,在es5種可以對這些特性進行配置(之後會討論)。

  • 除了包含普通屬性之外,每個物件還包含三特相關特性(object attribute)

    1. 物件的原型(prototype),指向一個物件,本物件可以繼承該物件的屬性。
    2. 物件的類(class),標識物件型別的字串。
    3. 物件的擴充套件標記(extensible flag)指明是否可以向該物件新增新的屬性。

三. 建立物件

(一)物件直接量

物件直接量,是指在js程式碼中,用大括號將鍵值對包含在一起,屬性之間用逗號隔開,鍵值對用冒號連線的形式直接建立一個物件。

物件直接量是一個表示式,這個表示式運算過程中,會建立並初始化一個新的物件。

	var empty = {}; //沒有任何屬性的物件
	var point = { x:0,y:0}  //兩個屬性
	var point2 = {x:point.x, y:ponit.y+1} //更多屬性
	var book = {
		"main title":"JavaScript", //字串中可以帶空格
		"sub-title":"The Defintitive Guide", //屬性名字裡有-
		"for":"all audiences",  //"for"是保留字,必須用引號
		author:{				//單純屬性名可以不用引號	
			firstname:"David" 
		}
	}
複製程式碼

注意:

  1. 在ES5中,保留字可以用作不帶引號的屬性名。但是對於大部分的ES3實現,保留字作為屬性名必須用引號引起來。
  2. 在ES5&ES3的大部分實現中,物件直接量最後一個逗號會被忽略,但是ie中會報錯。

(二)通過new建立物件

new雲算符建立並初始化一個新物件,關鍵字new後跟隨一個函式呼叫。這裡的函式即是建構函式(constructor)。js語言核心包含內建建構函式

	var o = new Object();//建立一個空物件,和{}作用相同
	var a = new Array();//建立一個空陣列,和[]作用相同
	var d = new Date();//建立一個表示當前時間的Date物件
	var r = new RegExp("js");//建立一個進行模式匹配的RegExp物件
複製程式碼

(三) 通過Object.create()建立

1.原型 在介紹Object.create()之前,先要了解一下原型的概念。 每個js中的物件(除了null)都與一個物件相關聯,這個關聯的物件就是原型,每個物件都從原型中繼承屬性。

  • 所有通過物件直接量建立的物件都具有同一個原型物件,並通過js程式碼Object.prototype獲得該物件的引用。
  • 通過關鍵字new和建構函式呼叫建立的物件的原型就是建構函式的prototype屬性的值。
  • js實現中,大部分物件都有原型,Object.prototype就是其中之一。
  • 一個物件往上查詢,會有一個連續繼承的原型結構,這個就是是所謂的原型鏈。

2.Object.create()

ES5中定義了Object.create()的方法,它創接受兩個引數,第一個引數是這個物件的原型,第二個可選引數用以描述本物件。本函式是一個靜態函式。

	var o1 = Object.create({x:1,y:2}); 
	//o1將繼承x和y這兩個屬性。
複製程式碼

Object.create()通過傳入null,可以建立一個沒有原型的,真正意義上的空物件,該物件不會繼承任何東西,甚至不包括基本方法,如toString(),如果想建立一個普通的空物件,則必須傳入Object.prototype

	var o3 = Object.create(Object.prototype); 
	//如此建立的o3行為和{}和new Object()完全一樣。
複製程式碼

Object可以通過原型建立物件,也就是說,你可以通過這個方法,建立一個繼承任意物件的物件,不過這個方法來自es5標準,在某些es3實現中,可以用如下方法模擬:

	function inherit(p){  //inherit即為繼承,引數為要繼承的原型
		if(p==null) throw TypeError();	//p不能是null
		if(Object.create)	//如果支援Object.create的話直接呼叫
			return Object.create(p);
		var t = typeof p;
		if(t!=="object"&&t!=="function") throw TypeError();  //否則進一步檢測
		function f(){};	//定義一個空的建構函式f
		f.prototype = p; //將f的建構函式設定為p
		return new f();	//使用f()建立p的繼承物件
	}	
複製程式碼

當然這個方法並不完善,第一inherit()不能接受null,第二inherit()不能接受第二個引數。

概述和建立物件的重點記錄到這裡,下一節將更關注物件本身的操作,我會不定期補充知識點和注意事項。

相關文章