What?
每创建一个函数都会有一个默认有一个prototype属相,该属性是一个对象。作用为:所有特定类型的所有实例共享该该对象包含的属性和方法。通俗讲:prototype对象就是通过调用构造函数创建的
那个对象的原型对象。
好处:让所有的实例对象都可共享它的属相和方法(所以不必在构造函数中定义对象的信息,直接将这些信息添加到原型中,供所有的实例对象使用)
function Box(){}; //创建构造函数
创建构造函数的原型有两种方法:
一种:直接赋值
Box.prototype.name='lee'; //在原型中添加属性
Box.prototype.age='18';
Box.prototype.run=function(){ //在原型中添加方法
return this.name+this.age+'运行中...'
}
另一种:字面量方式声明
Box.prototype={
name:'lee',
age:18,
run:function(){
return this.name+this.age+'运行中...'
}
};
两种方式的不同点:原型创建的方式,实例对象的constructor属性值不是构造函数,而是Object
alert(box1.constructor== Box); //false
alert(box1.constructor== Object); //true
如果想让它是构造函数,可以这样写:
Box.prototype={
constructor:Box, //直接强制指向
name:'lee',
age:18,
run:function(){
return this.name+this.age+'运行中...'
}
};
那么问题又来了,为什么指向的是Object,实例化的是构造函数???
因为Box.prototype={};这样写其实就是再创建新对象了,而每创建一个函数就会同时创建它的prototype,这个对象也会自动获取constructor属相,所以新对象的constructor重写了Box原来的constructor,因此会指向新对象,那这个新对象没有指定构造函数,默认就是Object.
创建对象:
box1=new Box();
box2=new Box();
而创建的这两个对象的方法的引用地址是一样的:
alert(box1.run==box2.run);
How?
为什么会一样那,下面利用2副图说明问题根源
构造函数的声明方法:
原型的声明方式:
由上面可看出:利用构造函数声明的原型的所有实例对象通过构造函数的proto指针都指向了同一个构造函数Box的prototype,都访问它里面的属性和方法
那么问题来了,我怎么知道对象是否指向了prototype???
Box.prototype.isPrototypeOf(box1)
原型模式的执行流程
1.先查找构造函数声明的实例有没有属性或方法,有,则使用实例对象的属相和方法,立刻返回
2.如果没有,则去原型对象中去找,有,则返回
虽然可以通过实例对象可以访问原型中的值,但不能通过实例对象重写原型中的值,如果我们不想再使用原型中的值,我们可以通过实例对象再次赋值,但是原型中的属性值没变,别的对象仍然访问的是原型中的值
box1=new Box();
box1.name='shuang';
如果同一个对象想再次访问原型中的值,可以删除构造函数(即实例对象)里的属性即可:
delete box1.name //删除属性
如果我就想改原型里的属性值或方法,可以重写原型,新重写的原型会切断原来的原型
那么问题来了,我怎么知道该对象访问的属相是构造函数的实例里的,还是原型中的?通过hasOwnProperty()函数来验证:
box1.hasOwnProperty("name") //返回true,表明是构造函数的实例里的,false,是原型里的
hasOwnProperty()函数只能判断访问的属性是否是构造函数实例对象里的吗,返回false,有2中情况,1种是根本没有该属性,另一种是原型中的,那么我怎么知道是否是原型中的那,还有一个函数in(),判断有无该属性
alert('name'inbox);
综合利用这2个函数即可判断:
functionisProperty(object, property) { //判断原型中是否存在属性
return!object.hasOwnProperty(property) &&(propertyinobject);
}
varbox=newBox();
alert(isProperty(box,'name')) //true,如果原型有