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内的属性