原型模式:每创建一个函数都有一个prototype属性,它是一个指针,指向一个对象;
 
原型模式创建函数的方式:
 
 
 
 1 function Movie(){
 2 
 3 };
 4 Movie.prototype.name="Interstellar";
 5 Movie.prototype.year=2014;
 6 Movie.prototype.country="American";
 7 Movie.prototype.playMovie=function(){
 8    alert(this.name);
 9 }
10 
11 var movie1=new Movie();
12 movie1.playMovie();//Interstellar;
13 var movie2=new Movie();
14 movie2.playMovie();//Interstellar;
15 
16 alert(movie1.playMovie==movie2.playMovie);//true 有别于构造函数
 
对象字面量的方式
 
 
 
 1 function Movie(){
 2 
 3 };
 4 Movie.prototype={
 5      name:"Interstellar",
 6      year:2014,
 7      country:"American",
 8      playMovie:function(){
 9        alert(this.name);
10 }
11 }
12 //这种方式原型对象的contructor属性不会指向Movie了,而是指向Object了。
 
每当代码读取某个属性时,都会先搜索对象实例本身,没有就继续搜索指针指向的原型对象,如果有就结束;通过hasOwnProperty()可以检测属性是存在实例中还是原型中:
 
 
 
 1 function Movie(){
 2 };
 3 Movie.prototype.name="FleetOfTime";
 4 Movie.prototype.year=2014;
 5 Movie.prototype.country="China";
 6 Movie.prototype.playMovie=function(){
 7    alert(this.name);
 8 }
 9 var movie1=new Movie();
10 alert(movie1.hasOwnProperty("name"));//原型上的 false
11 movie1.name="xxxx";
12 alert(movie1.hasOwnProperty("name"));//覆盖了原型上的,变成实例上的了  true
 
原型的动态性:对原型对象所做的任何修改都能够立即从实例中反映出来,例:
 
 
 
1 var movie=new Movie();
2 Movie.prototype.playOne=function(){
3     alert("One");
4 };
5 movie.playOne();//"One"
7 //给Movie原型对象添加了一个方法
 
但是如果是重写整个原型对象的话,那么就等于切断了构造函数与最初原型之间的联系了:
 
 
 
 1 function Movie(){
 2 
 3 }
 4 
 5 var movie=new Moive();
 6 //重写原型对象
 7 Movie.prototype={
 8     constructor:Movie,//对象字面量方式强制指向Movie,本来指向Object
 9     name:"xxx",
10     year:2012,
11     country:"xxxx",
12     sayName:function(){}
13 }
14 //这时候调用sayName()方法会出错
15 movie.sayName();//error   
 
 
 
原型对象的问题:对于包含引用类型值的属性来说,就有很大问题了,如下例子
 
 
 
 1 function Movie(){
 2 }
 3 Movie.prototype={
 4      constructor:Movie,
 5      name:"xxx",
 6      year:2014,
 7      place:["China","Japan"],
 8      playName:function(){
 9          alert(this.name);
10 }
11 }
12 var movie1=new Movie();
13 var movie2=new Movie();
14 
15 movie1.place.push("korea");
16 
17 alert(movie1.place)//"China,Japan,Korea"
18 
19 alert(movie2.place)//"China,Japan,Korea"
20 
21 //这里本来是想只改变movie1的place,结果也改到了movie2的
 
 
 
最好的创建对象方式:构造函数来定义实例属性,原型模式来定义方法和共享属性;
 
 
 
 1 function Movie(name,year,country){
 2      this.name=name;
 3      this.year=year;
 4      this.country=country
 5      this.place=["China","Japan"];
 6 }
 7 Movie.prototype={
 8        constructor:Movie,
 9        playName:function(){
10               alert(this.name);
11 }
12 }
13 
14 var movie1=new Movie("Interstellar",2014,"American");
15 var movie2=new Movie("FleetOfTime",2014,"China");
16 movie1.place.push("Korea");
17 alert(movie1.place);//"China,Japan,Korea"
18 alert(movie2.place);//"China,Japan"
19 
20 alert(movie1.place==movie2.place);//false
21 alert(movie1.playName==movie2.playName);//true