JavaScript之prototype对象
简述prototype:
在js中,每个构造函数都有一个原型属性prototype,因为这个属性的值通常是一个对象,又叫原型对象!你不需要显式的去定义原型对象,因为每个构造函数都会一个原型属性,通常在这个原型对象中,会包含一个constructor属性指向该原型对象的构造函数:
function a() { alert('hello'); } var b = new a(); console.log(b.constructor);//返回函数a的字面量function a() {alert('hello')} ;
以上代码中你会发现,首先你并没有定义函数a的prototype,以及constructor;但是在使用的时候构造函数a的实例对象b的constructor属性却正确的指向构造函数a;
我们都知道js是一种基于原型继承的语言,这里说的原型指的就是对象的原型属性!从这就能看出来,在js中,原型是用来实现继承的!那么为什么可以通过对象的原型就能实现继承了?这是因为在js中,所有使用同一个构造函数生成的实例对象,都共享该构造函数的原型对象,例如:
//定义构造函数 function user(name, age) { this.name = name; this.age = age; } //定义构造函数user的原型方法 user.prototype.getName = function() { alert(this.name); } user.prototype.getAge = function() { alert(this.age); } //生成实例 var userA = new user('a', '22'); var userB = new user('b', '30'); userA.getName();//a userA.getAge();//22 userB.getName();//b userB.getAge();//30
由以上代码可以看出,在构造函数中我们并没有定义获取名称和获取年龄的方法getName以及getAge;它们是在原型对象中定义的;但是我们在底下代码中的user构造函数的两个实例对象userA和userB却都可以使用构造函数的原型对象中的方法!这就是上面说的:所有使用同一个构造函数生成的实例对象,都共享该构造函数的原型对象!
prototype中的constructor属性:
上面简单的介绍了一下prototype中的constructor属性,该属性是原型对象中自带的属性,并且它始终是指向该原型的构造函数的!
//定义构造函数 function user(name, age) { this.name = name; this.age = age; } //定义构造函数user的原型方法 user.prototype.getName = function() { alert(this.name); } user.prototype.getAge = function() { alert(this.age); } //生成实例 var userA = new user('a', '22'); var userB = new user('b', '30'); console.log(userA.constructor === userB.constructor)//true;
当然,我们也可以动态的设置constructor属性的值:
user.prototype.constructor = user;
只是在我们没有重新定义覆盖prototype对象的时候,并不需要这样显示的去让constructor属性指向构造函数!
覆盖prototype对象:
上面我们简单介绍了prototype对象,并且也给出来一些简单使用的例子,在上面的例子中,我们都是往构造函数的prototype对象上添加方法或属性的,有一个方法我们就要添加一次,这样显的不够优雅,那么有没有一种写法是可以一次定义这些方法的了?答案当然是肯定的,这就是我们下面要讲的覆盖prototype对象,我们先来看看怎么做,下面我们重写上面的例子:
//定义构造函数 function user(name, age) { this.name = name; this.age = age; } //定义构造函数user的原型方法 user.prototype = { constructor : user, getName : function() { alert(this.name); }, getAge : function() { alert(this.age); } }
大家可以复制上面的代码,看看效果是不是跟之前的效果一样!相信大家看了代码之后应该也都明白了,既然prototype是一个对象,那么我们当然能重新定义一个对象去覆盖它了,但是这里值得注意的是,在原型对象中,默认是包含constructor属性指向构造函数的,在我们自己定义对象覆盖prototype对象时,要显式的定义constructor属性指向构造函数,否则,这个prototype对象的constructor属性就会是undefined!
总结:
说到这里,关于prototype对象的一些知识以及基本用法,已经跟大家交代清楚了,因为js是基于原型继承的,所以了解prototype对象的相关对象,对于js面向对象编程是至关重要的!关于prototype的部分我们就先讲到这里,等以后有时间,我们在接着讲原型链,面向对象以及js中的继承等知识!
感谢大家的阅读,本文由平凡公子原创发布,转载请注明出处,谢谢!