js原型

看javascript高级程序设计里关于函数原型的内容,感到一知半解。又百度了几篇关于函数原型的博客文章,对原型有了个大概的理解。

首先,为什么要使用原型?看下面的例子:

 1         function MyApple(name){
 2             this.name=name;
 3             this.sayName= function () {
 4                 alert(this.name);
 5             }
 6         }
 7         var apple1=new MyApple("apple1");
 8         var apple2=new MyApple("apple2");
 9         apple1.sayName();
10         apple2.sayName();

如上述代码所示,每次新建一个实例,所有属性都会拷贝进这个实例中,造成了内存的浪费。因此,我们需要别的方法来避免这种浪费。使用原型的话,并不会将所有属性拷贝到所有实例中,而是所有实例共享原型内部定义的方法。

 1         function MyApple(){
 2 
 3         }
 4         MyApple.prototype.name="apple1";
 5         MyApple.prototype.sayName= function () {
 6             alert(this.name);
 7         }
 8         var apple1=new MyApple();
 9         var apple2=new MyApple();
10         apple2.name="apple2";
11         apple1.sayName();
12         apple2.sayName();

如上述代码所示,所有实例共享prototype定义的所有方法,不仅如此,js还可以动态添加属性和方法,如果想要添加的属性和方法被实例使用,就要使用原型添加。

 1         function MyApple(){
 2 
 3         }
 4         MyApple.prototype.name="apple1";
 5         MyApple.prototype.sayName= function () {
 6             alert(this.name);
 7         }
 8         var apple1=new MyApple();
 9         var apple2=new MyApple();
10         apple2.name="apple2";
11         apple1.sayName();
12         apple2.sayName();
13         MyApple.prototype.eatApple= function () {
14             alert("I have eat it!");
15         }
16         apple1.eatApple();//I hava eat it!

constructor一直指向prototype,因此当prototype指向的函数发生变化时,constructor的指向也会发生变化,因此如果想要constructor指向原定义的函数,可以function.prototype.constructor=function;

 1         function Friuts(name){
 2             this.name=name;
 3         }
 4         function Apple(size){
 5             this.size=size;
 6         }
 7         Apple.prototype=new Friuts();
 8         //Apple.prototype.constructor=Apple;
 9         var apple=new Apple("big");
10         alert(apple.constructor.prototype==Apple.prototype);

上述代码中,apple.constructor.prototype是Fruits的原型,只具有属性name,而Apple.prototype是Apple的原型,具有name、size这两个属性,因此输出为false。但如果将第八句话取消注释,那么apple.constructor.prototype同样是Apple的原型,因此输出true。

那么,为什么会是上述这种结果呢?原因很简单——继承。Apple.prototype=new Friuts();Apple继承了Friuts的属性,但同时也保留了自己的属性size。因此,在访问属性时,会先访问实例的属性,如果实例不存在该属性,才会访问原型指向的函数的属性,若原型指向的函数不存在该属性,那么就会访问Object是否存在该属性。

 1         function Friuts(){
 2             this.name="JInshuai";
 3         }
 4         function Apple(size){
 5             this.name="Fushi";
 6             this.size=size;
 7         }
 8         Apple.prototype=new Friuts();
 9         //Apple.prototype.constructor=Apple;
10         var apple=new Apple("big");
11         alert(apple.name);//Fushi
12         alert(apple.size);//big
13         Object.prototype.isSweet= function () {
14             alert("It is so sweet!");
15         }
16         apple.isSweet();//It is so sweet!

 

posted @ 2016-03-16 16:56  冰凝夢  阅读(169)  评论(0编辑  收藏  举报