JavaScript设计模式-原型模式

原型模式:将一个类的原型指向另个一类(实例化对象)的原型,实现对类的原型的共享。实现原理是基于JavaScript的原型链(prototype)

 

1.JavaScript中,所有函数(类)和部分原始数据类型(Number,String,Array,Function)具有prototype属性。

2.在类的prototype属性上设置的属性,所有实例共享。

3.实例可修改prototype上的属性。

  如果修改的是值类型,只是当前实例发生更改。

  如果修改的是引用类型,又分两种情况:

    ①如果直接修改引用类型,则只影响当前实例的值。且修改后,由于引用地址的变化,之后所有对该实例上该属性的更改都只作用于该实例。

    ②如果修改引用类型的属性或项,则对父类发生更改,影响所有实例的值。

4.类可以直接设置静态属性,可直接通过 ”类名.属性名 = 值 “设置和访问,实例不可访问。

  

 1 var Person=(function(){
 2     var personCount=0;
 3     function myPerson(name){
 4         this.name=name;
 5         personCount++;
 6         console.log('created new person,current person count:',personCount);
 7     }
 8 
 9     //静态属性,外部可通过Person.country直接访问,实例不可访问
10     myPerson.country='china';
11     myPerson.prototype={
12         //值类型,实例可修改,修改只影响当前实例
13         age:20,
14         //引用类型,实例可修改,修改里面的属性会影响所有实例
15         address:{
16             province:'四川',
17             city:'成都'
18         },
19         sayHello:function(){
20             console.log('hi,my name is ',this.name,',i am ',this.age);
21         },
22         myAddress:function(){
23             console.log(this.address.province,this.address.city);
24         }
25     };
26     return myPerson;
27 }());
28 
29 console.log(Person.country);
30 
31 var person1=new Person('zhangsan');
32 person1.sayHello();
33 var person2=new Person('lisi');
34 person2.sayHello();
35 var person3=new Person('wangww');
36 person3.sayHello();
37 
38 //修改值类型原型属性
39 person1.age=18;
40 console.log('修改person1.age后:');
41 person1.sayHello();
42 person2.sayHello();
43 person3.sayHello();
44 
45 //1修改引用类型原型属性的属性
46 person1.myAddress();
47 person2.myAddress();
48 person3.myAddress();
49 person1.address.city='德阳';
50 console.log('修改person1.address.city后:');
51 person1.myAddress();
52 person2.myAddress();
53 person3.myAddress();
54 
55 //2修改引用类型原型属性
56 person1.address={
57     province:'四川',
58     city:'巴中'
59 };
60 console.log('修改person1.address后:');
61 person1.myAddress();
62 person2.myAddress();
63 person3.myAddress();
64 
65 //3再次修改引用类型原型属性的属性
66 person1.address.city='绵阳';
67 console.log('修改person1.address.city后:');
68 person1.myAddress();
69 person2.myAddress();
70 person3.myAddress();
71 
72 //4再次修改引用类型原型属性的属性
73 person2.address.city='自贡';
74 console.log('修改person2.address.city后:');
75 person1.myAddress();
76 person2.myAddress();
77 person3.myAddress();

 

Console结果:

结果解析:

 ①第一次修改:修改person1.address.city=‘德阳’。此时,person1实例没有address属性,于是原型链向上查找,找到Person.prototype的address属性,将Person.prototype.address值修改为‘德阳’。访问三个实例的myAddress方法,由于三个实例均无address属性,则都根据原型链查找到Person.prototype.address,结果为‘德阳’

②第二次修改:修改实例person1.address={province:'四川',city:'巴中'}。该操作将一个新的对象赋值给person1的address属性,未对Person.prototype产生任何更改。访问三个实例的myAddress方法,由于person1已有属性address,则不再向上查找原型链,直接返回address的值。person2、person3均无address属性,则都根据原型链查找到Person.prototype.address,结果为‘德阳’

③第三次修改:再次修改person1.address.city=‘绵阳’。此时person1已有属性address,则不再向上查找原型链,直接修改person1的address属性的city属性,不对Person.prototype.address造成任何修改。访问三个实例的myAddress方法,由于person1已有属性address,则不再向上查找原型链,直接返回address修改后的值,返回‘绵阳’。person2、person3均无address属性,则都根据原型链查找到Person.prototype.address,结果为‘德阳’

④第四次修改:修改实例person2.address.city='自贡'。此时,person2实例没有address属性,于是原型链向上查找,找到Person.prototype的address属性,将Person.prototype.address值修改为‘自贡’。访问三个实例的myAddress方法,由于person1已有属性address,则不再向上查找原型链,直接返回address的值,返回‘绵阳’。person2、person3均无address属性,则都根据原型链查找到Person.prototype.address,结果为‘自贡’

 

posted @ 2018-09-19 22:16  这是一个低调的昵称  阅读(933)  评论(0编辑  收藏  举报