JavaScript 物件

cactusz發表於2017-07-06

物件與陣列
JavaScript中的物件本質上是一個關聯陣列,或者說更像java裡的?Map資料結構,由key-value組成。如下:

<script>
	function Person(name , age)
	{
		//將name、age形參的值分別賦給name、age例項屬性。
		this.name = name;
		this.age = age;
		this.info = function()
		{
			alert('info method!');
		}
	}
	var p = new Person('yeeku' , 30);
	for (propName in p)
	{
		//遍歷Person物件的屬性
		document.writeln('p物件的' + propName 
			+ "屬性值為:" + p[propName] + "<br />");
	}
</script>
 


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
JavaScript物件都都基於相同基類(Object)的例項,因此所有的JavaScript物件之間沒有明顯的繼承關係,而且JavaScript是一種動態語言,它允許自由地為物件增加屬性和方法,當程式為物件的某個不存在的屬性賦值時,即可認為是為該物件增加屬性。例如:
var p={};
p.age=30;
p.info=function(){
alert("info menthod");
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
關於prototype

<script>    
	//建立Person函式
	function Person(name , age)
	{
		this.name = name;
		this.age = age;
		//為Person物件指定info方法
		this.info = function()
		{
			//輸出Person例項的name和age屬性
			document.writeln("姓名:" + this.name);
			document.writeln("年齡:" + this.age);
		}
	}
	//建立Person例項p1
	var p1 = new Person('yeeku' , 29);
	//執行p1的info方法
	p1.info();
	document.writeln("<hr />");
	//建立Person例項p2
	var p2 = new Person('wawa' , 20);
	//執行p2的info方法
	p2.info();
</script>
 上述程式碼定義了Person函式的同時,也定義了一個Person類,而且該函式就是該Person類的構造器。
但上面為Person物件增加info方法相當不好,有兩點原因:
1,效能低下:每次建立例項都會建立info()函式,會造成記憶體洩漏,引起效能下降,實際上info()方法一個就好了
2,使得info()函式中的區域性變數產生閉包:閉包會擴大區域性變數的作用域,使得區域性變數一直存活到函式之外的的地方。例如:

<script>
	//建立Person函式
	function Person()
	{
		//locVal是個區域性變數,原本應該該函式結束後立即失效
		var locVal = '瘋狂Java聯盟';
		this.info = function()
		{
			//此處會形成閉包
			document.writeln("locVal的值為:" + locVal);
			return locVal;
		}
	}
	var p = new Person();
	//呼叫p物件的info()方法
	var val = p.info();
	//輸出val返回值,該返回值就是區域性變數locVal。
	alert(val);
</script>
 
為了避免這兩種情況,通常不在函式定義(也就是類定義)中直接為該函式定義方法,而是使用prototype屬性。JavaScript所有的類(也就是函式)都有一個prototype屬性,在為JavaScript類的prototype屬性增加函式,屬性時,即可視為對原有的的擴充套件。我們可以理解為增加了prototype屬性的類繼承了原有的類——這就是JavaScript所提供的偽繼承機制。
如下:

<script>
	//定義一個Person函式,同時也定義了Person類
	function Person(name , age)
	{
		//將區域性變數name、age賦值給例項屬性name、age
		this.name = name;
		this.age = age;
		//使用內嵌的函式定義了Person類的方法
		this.info = function()
		{
			document.writeln("姓名:" + this.name + "<br />");
			document.writeln("年齡:" + this.age + "<br />");
		}
	}
	//建立Person的例項p1
	var p1 = new Person('yeeku' , 29);
	//執行Person的info方法
	p1.info();
	//此處不可呼叫walk方法,變數p還沒有walk方法
	//將walk方法增加到Person的prototype屬性上
	Person.prototype.walk = function()
	{
		document.writeln(this.name + '正在慢慢溜達...<br />');
	}
	document.writeln('<hr />');
	//建立Person的例項p2
	var p2 = new Person('leegang' , 30);
	//執行p2的info方法
	p2.info();
	document.writeln('<hr />');
	//執行p2的walk方法
	p2.walk();
	//此時p1也具有了walk方法——JavaScript允許為類動態增加方法和屬性
	//執行p1的walk方法
	p1.walk();
</script>
偽繼承實質上是修改了原來的類,而不是產生一個新的之類,所以原來沒有walk()方法的Person類將不存在了。 
上面的程式也說明了JavaScript是一門動態語言,不僅可以為物件動態增加屬性和方法,還可以為動態增加屬性和方法!



還可以通過使用prototype屬性,可以對JavaScript的內建類進行擴充套件。如下:
<script>
	//為Array增加indexof方法,將該函式增加到prototype屬性上
	Array.prototype.indexof = function(obj)
	{
		//定義result的值為-1
		var result = -1;
		//遍歷陣列的每個元素
		for (var i = 0 ; i < this.length ; i ++)
		{
			//當陣列的第i個元素值等於obj時
			if (this[i] == obj)
			{
				//將result的值賦為i,並結束迴圈。
				result = i;
				break;
			}
		}
		//返回元素所在的位置。
		return result;
	}
	var arr = [4, 5, 7, -2];
	//測試為arr新增的indexof方法
	alert(arr.indexof(-2));
</script>
 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

與傳統物件導向程式設計語言不同的是,JavaScript中的函式永遠是獨立的,函式永遠是一等功民,函式永遠不會從屬於其他類,物件。即使這個還個函式是匿名內嵌函式。如下:

<script>
	//定義Dog函式,等同於定義了Dog類
	function Dog(name , age , bark)
	{
		//將name、age、bark形參賦值給name、age、bark例項屬性
		this.name = name;
		this.age = age;
		this.bark = bark;
		//使用內嵌函式為Dog例項定義方法
		this.info = function()
		{
			return this.name + "的年紀為:" + this.age
				+ ",它的叫聲:" + this.bark;
		}
	}
	//建立Dog的例項
	var dog = new Dog("旺財" , 3 , '汪汪,汪汪...');
	//建立Cat函式,對應Cat類
	function Cat(name,age)
	{
		this.name = name;
		this.age = age;
	}
	//建立Cat例項。
	var cat = new Cat("kitty" , 2);
	//將dog例項的info方法分離出來
	var tmp = dog.info;
	//通過function的call方法完成cat的呼叫info方法
	alert(tmp.call(cat));
</script>
 JavaScript中的方法呼叫有兩種方式:
1,正常方法    obj.method(args...)
2,方法回撥    method.call(obj,args...)


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
JavaScript建物件
大致三種方法:
使用關鍵字new建立物件

<script>
	//定義一個函式,同時也定義了一個Person類
	function Person(name , age)
	{
		//將name、age形參賦值給name、age例項屬性
		this.name = name;
		this.age = age;
	}
	//分別以兩種方式建立Person例項
	var p1 = new Person();
	var p2 = new Person('yeeku' , 29);
	//輸出p1的屬性
	document.writeln("p1的屬性如下:"
		+ p1.name + p1.age + "<br />");    
	//輸出p2的屬性
	document.writeln("p2的屬性如下:" 
		+ p2.name + p2.age);
</script>
 

使用Object建立即時物件

<script>
	var myObj = new Object();
	myObj.info = new Function("document.writeln('物件的name屬性:' + this.name);"
		+ "document.writeln('<br />');"
		+ "document.writeln('物件的age屬性:' + this.age)");
	document.writeln("<hr / >");
	myObj.name = 'yeeku';
	myObj.age = 29;
	//為物件增加方法
	
	myObj.info();
</script>



<script>
	//建立空物件
	var myObj = new Object();
	//為空物件增加屬性
	myObj.name = 'yeeku';
	myObj.age = 29;
	//建立一個函式
	function abc()
	{
		document.writeln("物件的name屬性:" + this.name);
		document.writeln("<br />");
		document.writeln("物件的age屬性:" + this.age);
	};
	//將已有的函式新增為物件的方法
	myObj.info = abc;
	document.writeln("<hr>");
	//呼叫方法
	myObj.info();
</script>
 

使用JSON語言建立物件

<script>
	//程式碼
	var person =
	{
		//定義第一個簡單屬性
		name : 'wawa',
		//定義第二個簡單屬性
		age : 29 ,
		//定義第三個屬性:陣列
		schools : ['小學' , '中學' , "大學"],
		//定義第四個屬性,物件陣列
		parents :[
			{
				name : 'father',
				age : 60,
				address : '廣州'
			} 
			,
			{
				name : 'mother',
				age : 58,
				address : '深圳'
			}
		],
              //定義方法
              info:function(){
              alert("hello world");
               }
	};
	alert(person.parents[0].name);
</script>
 







相關文章