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,結果為‘自貢’

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM