高級面向對象之 面向對象中常用的屬性和方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>面向對象中的常用屬性和方法</title>
	</head>
	<body>
		<script>
			面向對象中的常用屬性和方法:
			(1)hasOwnProperty() : 看是不是對象對象自身下面的屬性
			(2)constructor : 查看對象的構造函數
					->:每個原型都會自動添加constructor屬性
					->:for in 的時候有些屬性是找不到的
					->:避免修改constructor屬性
			(3)instanceof : 運算符
					->:查看對象與構造函數在原型鏈上是否有關係
			(4)toString():object對象上的方法
			
			demo1:
			
			var arr = [];
			arr.num = 10;
			Array.prototype.num2 = 20;
			alert(arr.hasOwnProperty('num'));  // true
			alert(arr.hasOwnProperty('num2')); // false
			demo1中 我們可以看出num是對象arr自身下面的屬性,num2不是對象arr下面的屬性,而是數組對象Array原型對象下面的屬性
			
			demo2: constructor使用
			
			function Aaa(){
				
			}
			var a1 = new Aaa();
			alert(a1.constructor);   // Aaa
			var arr = [];
			alert(arr.constructor);  // Array
			但是這個constructor屬性是哪裏來的呢?
			原來 當我們定義一個對象後,系統會自動添加一行代碼,以上面的Aaa對象爲例,當我們定義了
			一個對象 Aaa之後(function Aaa(){}),系統會自動添加下面這行代碼:
			Aaa.prototype.constructor=Aaa;就是說當我們定義了一個對象後,程序會自動給我們添加一個construcor屬性,
			它是一個指針,指向該對象的構造函數,
			因此我們可以利用constructor屬性來判斷一些對象的類型,如:
			var arr = [];
			alert(arr.constructor == Array); // true
			
			demo3:
			但是我們可以修改constructor,如
			function Aaa(){
				
			}
			Aaa.prototype.constructor = Array;
			var a1 = new Aaa();
			alert(a1.constructor == Aaa);  // false
			此時我們修改了系統爲Aaa對象默認添加的constructor屬性,此時Aaa的constructor屬性不再指向Aaa,而是Array
			但是我們儘量不要修改constructor屬性
			
			demo4: 我們有時候不經意就把constructor屬性值該掉了
			function Aaa(){
			}
			
			Aaa.prototype.name='小明';
			Aaa.prototype.age = 20;
			
			var a1 = new Aaa();
			alert(a1.constructor); // Aaa
			
			但是當我們這樣寫時(簡寫):
			Aaa.prototype={
				name:'小明',
				age:20
			}
			
			alert(a1.constructor);  //Object
			
			這是爲什麼呢? 以爲這種寫法相當於我們把一個json對象{name:'小明',age:20}賦值給了Aaa的原型對象,
			json 對象有自己的constructor,此時我們就不經意間修改了Aaa的默認constructor屬性,
			但是我們可以手動矯正,把constructor 屬性的指向給修正過來:
			
			Aaa.prototype={
				constructor:Aaa,
				name:'小明',
				age:20
			}
			這樣constructor屬性又重新指向了Aaa
			
			demo5:通過for in 獲取對象屬性(自己添加的屬性可以知道,系統自帶的既原型鏈上的屬性是獲取不到的):
			
			var Aaa =function(){
				
			}
			
			for(var attr in Aaa.prototype){
				alert(attr);  //彈不出任何值
			}
			當我們給Aaa對象添加一個屬性時, Aaa.name='小明'; for in 便利就可以獲取到,彈出name
			
			2.instanceof
			它其實不是面向對象的屬性和方法,它其實是一個運算符,但是它的作用卻是跟面向對象有關的
			demo1:
			function Aaa (){
				
			}
			var a1 = new Aaa();
			alert(a1 instanceof Aaa);    // true
			alert(a1 instanceof Array);  //false
			alert(a1 instanceof Object); //true
			因此我們也可以利用instanceof做類型判斷
			
			3.toString(): 返回對象的字符串表示
			
			demo1:
			function Aaa(){
				
			}
			 var a1 = new Aaa();
			 alert(a1.toString == Object.prototype.toString); // true
			 結果爲true 表明 toString()方法來自於 Object
			 
			 Demo2: 與demo1比較
			 
			var arr =[];
			alert(arr.toString == Object.prototype.toString);  //false
			var arr2 = new String();
			alert(arr2.toString == Object.prototype.toString); // false
			
			demo1中對象是自定義對象,demo2中是系統對象,對比我們可以得出結論:
			
			toString()方法:--> 系統對象下面都是自帶的,自己寫的對象都是通過原型鏈找Object下面的
			
			demo3: 既然我們知道了toString方法的作用是返回對象的字符串表示,以及自定義對象的toString
					方法的出處我們就可以利用toString 方法達到下面的作用
					
					1:返回自定義的字符串樣式
					
						var arr =[1,2,3];
						alert(arr.toString()); // 1,2,3 系統默認的返回形式
						我們可以自定義返回形式:
						Array.prototype.toString = function(){
							return this.join('+');
						}
					
					alert(arr.toString());  // 1+2+3 得到我們自定義的返回形式,以加號連接
					
					2:進制轉換
					
						var num = 255;
						alert(num.toString(16)); // ff
						把整形的數值255 轉換爲16進制的字符表示, 因此我們可以利用這一特性
						實現顏色值的轉換(RGB和16進制顏色值相互轉換)
					
					3. 做類型判斷
				        	雖然我們可以利用 constructor 屬性和instanceof 做類型判斷,但是toString方法
				        	也可以用來做類型判斷
				     
						var arr=[];
						var arr2={};
						var arr3 = new Date();
						alert(Object.prototype.toString.call(arr));  // '[object Array]'
						alert(Object.prototype.toString.call(arr2)); // '[object Object]'
						alert(Object.prototype.toString.call(arr3)); // '[object Date]'
						通過結果可以看出,我們可以利用toString方法進行類型判斷,如:
						
						alert(Object.prototype.toString.call(arr) == '[object Array]');  // true
						
					4.總結:
						既然 constructor,instanceof,toString()這三個都能用來判斷類型,那麼哪一種最呢?
						答案是 使用toString()方法,它纔是最完美的判斷,基本上這三個我們都能用,但是在某些特殊的
						情況下 constructor和instanceof 就會出現問題,例如在iframe 中(跨頁面了),如下:
						
			 			window.onload = function(){
			 				var oF = document.createElement('iframe');
			 				document.body.appendChild(oF);
			 				var ifArray = window.frames[0].Array;  // 這個數組對象是iframe 下的數組對象
			 				
			 				// 創建一個數組對象實例arr,它其實是iframe下數組對象的實例,那就跨頁面了,
			 				// 雖然它是一個數組,但是它是在iframe下面的數組
			 				var arr = new ifArray();
			 				
			 				alert(arr.constructor == Array);   // false
			 				alert(arr instanceof Array);       // false
			 				alert(Object.prototype.toString.call(arr) == '[object Array]');  // true
			 			}
			 			// 綜上所述,使用toString方法判斷類型最好(當然大部分情況下,constructor和instanceof也能用)
		</script>
	</body>
</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章