首页 > 代码库 > javascrip原型模式创建对象
javascrip原型模式创建对象
要实现更高的数据代码共享,则应使用原型模式。
1.原型对象
在javascript中,我们创建函数时,都会有一个prototype属性即原型属性。这个属性是一个指针,指向一个对象,这个对象的用途就是实现实例的属性、方法共享。
在默认情况下,所有的原型对象都会自动获得一个constructor属性即构造函数属性,该属性指向原对象。
这个神马内存指向的图我是不会画。话说Visio能不能画这种图哇。有木有大神讲解一下~
反正就是:
Dog.prototype.constructor==Dog;//true
dog1.prototype.constructor==Dog;//true
也可以使用:
Dog.prototype.isPrototypeOf(dog1);//trueObject.getPrototypeOf(dog1)==Person.prototype;//true
虽然可以通过对象实例访问保存在原型中的值,但却不能通过实例重写原型中的值,如果我们在实例中添加了一个同名属性,则可以理解为同名覆盖(此处开辟内存)。
2.原型函数
function Dog(){}Dog.prototype.age=11;Dog.prototype.size=22;Dog.prototype.toAge=function(){ alert(this.age);};var dog1=new Dog();var dog2=new Dog();dog1.age=20;dog1.toAge();//20,来自实例dog2.toAge();//11,来自原型
delete操作符可以删除实例属性,从而让我们能够重新访问原型中的属性。
再提一句,hasOwnProperty()方法只有在实例重写属性之后才能访问。
而in操作符单独使用时,无论属性存在于实例中还是原型中,都可以访问。
除此之外,还有hasPrototypeProperty()函数用于访问原型中的属性。
要取得对象上所有可枚举的实例属性,可以使用Object.keys()方法。例如:
function Dog(){}Dog.prototype.age=11;Dog.prototype.size=33;Dog.prototype.toAge(){ alert(this.age);};var keys=Object.keys(Dog.prototype);alert(keys);//"age,size,toAge"var p1=new Dog();p1.age=10;p1.size=44;var p1keys=Object.keys(p1);alert(p1keys);//"age,size"
如果你想得到所有实例属性可以使用Object.getOwnPropertyNames()方法。用法如下:
var keys=Object.getOwnPropertyNames(Dog.prototype);alert(keys);//"constructor,age,size,toAge"
获取属性的方法就介绍到这里。//都闪开,都闪开,后面这段我要吹牛逼了,大家看看就行......
其实更简单的原型语法如下:
function Dog(){}Dog.prototype={ age:12, size:44, toAge:function(){ alert(this.age); }};var dog=new Dog;
但是这里实际上,完全重写了prototype对象,所以此时的原型对象的constructor属性已经不指向Dog函数了。例如:
alert(dog instanceof Object);//truealert(dog instanceof Dog);//truealert(dog.constructor==Object);//truealert(dog.constructor==Dog);//false
虽然使用instanceof还能返回正确结果,但是constructor已经无法确定对象的类型。但是依然可以为constructor设置为Dog。例如这样编写:
Dog.prototype={ constructor:Dog};
注意,重设构造函数只适用于ECMAScript5兼容浏览器。并且重设构造函数 会使默认的constructor变为可枚举的,您可以使用Object.defineProterty()函数改变。
Object.defineProterty(Dog.prototype,"constructor",{ enumerable:false;//设置为不可枚举 value:Dog});
在重写原型对象后,在重写之前的实例,属性即不可访问。
仔细理解:实例中的指针,仅指向原型,而不指向构造函数。重写了原型,则切断了函数与初始原型间的联系。实例依然指向初始原型,实例不可访问重写后原型的属性。
我这还有个问题,有木有大神帮忙解答,就是我能否访问实例的原型。为什么我是用dog1.prototype输出undefined。
顺便说一句,原生对象的方法也是在原型中定义的,如(Object,Array,String,等)。
javascrip原型模式创建对象