高级面向对象之 面向对象中常用的属性和方法

<!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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值