JS中prototype研究

来源:互联网 发布:保定软件技术学院电话 编辑:程序博客网 时间:2024/06/06 02:26
最近在学习JS,对于JS中的prototype不是很理解.所以对prototype做了一系列实验.有了一些体会.现在在这里分享一下

 

w3school对于prototype的介绍

 

Prototype

对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。

 

我对prototpye的是理解为他返回的是这个对象的引用.那么定义prototpye中放在函数名中的变量就是类的变量.

在定义过程中不能对prototype赋值。赋值不会起作用

但是,每个对象自己(this)没有他自己的prototype。

例如

function Person(){Person.prototype.username=new Array();Person.prototype.password="123";Person.prototype.showInfo=function(){alert(this.username+","+this.password);}}var p1= new Person();var p2 = new Person();var p3 = new Person();p1.username.push("asdf");p2.username.push("hello");p1.showInfo();p2.showInfo();p3.username.push("456");p3.showInfo();p1.showInfo();


 


实验结果为

p1的showInfo

p2的showInfo

p3的showInfo

 

p1的showInfo

从结果中我们看到当不同对象对数组进行push操作后,都是放入了同一个对象.在最后的p1.showInfo中显示的和p3相同,这个充分说明了他们公用的是一个对象,但这是不过是一个表面现象,如果就理解到这里,那么接下来的实验就会很困惑

第一个实验

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>无标题文档</title><script type="text/javascript">function Person(){Person.prototype.username="username";Person.prototype.password="123";Person.prototype.showInfo=function(){alert(this.username+","+this.password);}}var p1=new Person();var p2=new Person();p1.username="123";p1.showInfo();p2.showInfo();</script></head><body></body></html>


这个实验的结果本应该是p1与p2都是123但是实验的结果是

像个对象中的username不同,对于username他是一个prototype变量,本应该是对于整个对象来说,都是引用的一个username,所以修改p1,p2的username也会修改,这是为什么呢?

 

我在chrome中调试发现.当创建完一个对象后,在对这个对象赋值,那个值会变成一个对this的变量,就是这个函数(对象)的变量.而不是prototype变量

 

从这里看到p1的多了一个内部属性username这个值正好是123

而他prototype中的username仍未username没有变.

这说明这么赋值根本不是对prototype进行操作,而是在this中定义了一个变量是username

但是当调用为Person.prototype.username="123"时

结果变为两个值都是123

实验结果为对prototype的对象可以类似于this式的访问.要修改它的值时,会变为自定义属性.

 

 这里的_proto_与prototype是相同的.proto是每一个new出来的对象带有的.prototype是函数带有的.他们指向是相同的,但是IE中proto不可见

第二个实验

 

function Person(){Person.prototype.username=new Array();Person.prototype.password="123";Person.prototype.showInfo=function(){alert(this.username+","+this.password);}}var p1= new Person();p1.username.push("asdf");var p2 = new Person();p2.username.push("hello");p1.showInfo();p2.showInfo();var p3 = new Person();p1.showInfo();p2.showInfo();p3.username.push("456");p3.showInfo();p1.showInfo();


 


这个实验结果感觉 应该都是操纵的是同一个对象 那么结果是asdf,hello,456

 

但是真实的结果为

 

 结果与预想的相差很多.但是仔细分析一下,当每次创建一个对象时,都是执行一次函数,这个函数都会执行Person,prototype.username=new Array()

所以每次产生一个新对象,prototype中的值都会更新,

而在最开始中,三个对象都是在一起定义,所以不存在重复定义prototype变量的问题

,所以以后的解决方案应该是设置一个标记,只有在第一次调用函数时,才创建prototype变量

代码块如下

 

function Person(){if(typeof Person.flag=="undefined"){Person.prototype.username=new Array();Person.flag=true;}Person.prototype.password="123";Person.prototype.showInfo=function(){alert(this.username+","+this.password);}}var p1= new Person();p1.username.push("asdf");var p2 = new Person();p2.username.push("hello");p1.showInfo();p2.showInfo();var p3 = new Person();p1.showInfo();p2.showInfo();p3.username.push("456");p3.showInfo();p1.showInfo();


这样可以解决在不同地方创建Person时会重复定义prototype内的属性

 

 

原创粉丝点击