JavaScript prototype 属性和 对象属性、类属性的区别

在JavaScript中, 对象可以带属性,对象的原型(pototype)也可以带属性,类(Function对象)也可以带属性,那么这些属性有什么区别呢?

1、实验条件

首先声明一个类

var my fun = function(){}

(1)类的属性

myfun.name = 'Zhangsan';

(2)原型的属性

myfun.prototype.address = '北京东路88号';

(3)对象的属性

创建一个对象:

var myfun1 = new myfun();

myfun1.name2='Wangwu';


2、测试脚本

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>hasOwnProperty and in</title>
</head>

<body>
	<script lang="javascript">
		
		//创建一个类(class)
		var myfun = function(){
		
		}
		
		//设置prototype方法
		myfun.prototype.companyname = '3COM';		
		myfun.prototype.address='北京东路88号';
		myfun.prototype.postcode='210000';
		myfun.prototype.sayhello = function(name){
			alert('Hello '+ name + ' !');
		}
		
		//设置类的属性(放置在对象的constructor属性中)
		myfun.name = 'Zhangsan';
		
		//实例化
		var myfun1 = new myfun();
		
		//非对象属性,故访问不到
		alert('myfun1.name:' + myfun1.name);
		
		//通过构造器属性,可以访问到
		alert('myfun1.constructor.name:' + myfun1.constructor.name);
		
		//设置对象的属性
		myfun1.name2 = 'Wangwu';
		myfun1.address2 = '湖北路168号';
		myfun1.department ={
	    	code: '001',
	    	name:'研发中心'
		};
		
		//设置对象的方法(依然视作对象的属性)
		myfun1.func = function(){
			alert('test is ok!');
		}
 
	
		//实用函数
		function print(str){
			document.writeln(str + "<br>");
		}
	
	
		//打印对象非原型的属性
		function test(){
			var obj = myfun1;
			
			for(var n in obj) {
				if(Object.prototype.hasOwnProperty.call(obj, n)){
					print(n);				
				}			
			}
			print("--------------------------------------------------------");		
		}
	
	
		//打印对象所有属性
		function test2(){
			var obj = myfun1;
			
			for(var n in obj) {
					print(n);			
			}
			print("--------------------------------------------------------");		
		}
		
		
		test();		
		test2();
	</script>
</body>

</html>

3、分析总结

通过以上测试案例,可知三者之间区别如下:

a. 类属性:在其实例化对象中,只能通过构造器对象来访问。例子:

        //非对象属性,故访问不到
        alert('myfun1.name:' + myfun1.name);
        
        //通过构造器属性,可以访问到
        alert('myfun1.constructor.name:' + myfun1.constructor.name);

b. 原型属性;原型属性在内存中只会存在一份拷贝,对象实例化后并不能修改其值。

通过调试器观察对象,原型属性存在于对象的__proto__属性中,值不受外界影响。类似下面的赋值语句,实际上是给对象增加了新的属性,并未修改原型中的属性值。

myfun1.address='新的地址';

对象原型中的属性不能通过myfun1.__proto__.address来进行访问,因为__proto__属性对调用者不可见,只能通过对象的“类”来访问:

alert('myfun.prototype.address:' + myfun.prototype.address);

c.对象属性:在类被实例化后,给对象赋值,即为对象属性。对象属性时运用得最为广泛的一种属性,可以动态设置和获取。


4、prototype 属性和对象属性区分的实际应用

在某些场景下,需要区分出,哪些属性是原型所有,哪些属性时对象所有。使用的方法:

            for(var n in obj) {
                if(Object.prototype.hasOwnProperty.call(obj, n)){
                    print(n);                
                }            
            }

打印出非原型属性。

            for(var n in obj) {
                if(!Object.prototype.hasOwnProperty.call(obj, n)){
                    print(n);                
                }            
            }

打印出原型属性。

而使用for...in可以打印出所有的属性。实验结果如下:

name2
address2
department
func
--------------------------------------------------------
name2
address2
department
func
companyname
address
postcode
sayhello
--------------------------------------------------------
第一条虚线上为非原型属性,第一条虚线下为所有的属性。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值