对于javaScript设计模式的认知与学习
一、設計模式
設計模式: 它是一套編目分明、廣為人知、可復用的代碼經驗的總結
工具庫:一些常用方法的集合體,例如jQuery、underscore,這些方法之間通常是沒有聯系的
框架:一套半成品代碼,它里面也支持一些方法,但是這些方法之間通常是有聯系的
架構:一套大型項目的設計思路
1.1設計模式的分類
設計模式大致可以分為三類:
1 創建型設計模式
2 結構型設計模式
3 行為型設計模式
1.2設計模式的作用
創建型設計模式的作用: 解決了創建對象時候的問題
結構型設計模式的作用: 解決了對象和類組合在一起時候的問題
行為型設計模式的作用: 解決了對象和類耦合、職責之間的問題
1.3設計模式的歷史
設計模式最初是由國外的GOF(gang of four)合著完成,設計模式一共分為23種, 當發展至今已經遠遠超過23種
二、工廠模式
2.1 簡單工廠
實例代碼:
1function Factory(name, sex, age) {
2 // 聲明一個對象
3 var obj = {};
4
5 // 給對象添加屬性的過程
6 obj.name = name;
7 obj.sex = sex;
8 obj.age = age;
9
10 // 產生一個對象
11 return obj;
12}
2.2 寄生增強工廠
1function Person(name, sex, age) {
2 this.name = name;
3 this.sex = sex;
4 this.age = age;
5}
6
7// 添加say方法
8Person.prototype.say = function() {
9 console.log(‘this is say’);
10}
11
12// 寄生增強工廠
13function Factory(name, sex, age) {
14 // 獲得對象
15 var obj = new Person(name, sex, age);
16 // 添加自定義的屬性和方法
17 obj.hobby = ‘圍棋’;
18 obj.show = function() {
19 console.log(‘this is show’);
20 }
21
22 // 返回一個對象
23 return obj;
24}
2.3 工廠方法
1function Dog() {
2 this.name = ‘汪汪’;
3}
4
5function Cat() {
6 this.name = ‘喵喵’;
7}
8
9function Pig() {
10 this.name = ‘哼哼’;
11}
12
13// 工廠方法,會根據傳入的參數不同,產生不同的對象,但是不是直接產生,而是通過工廠調用產生
14function Factory(type) {
15 //根據你傳入的type的類別,產生對應的對象
16 if (type == ‘Dog’) {
17 return new Dog();
18 } else if (type == ‘Cat’) {
19 return new Cat();
20 } else if (type == ‘Pig’) {
21 return new Pig();
22 }。
23}
24
三、原型和繼承
原型:
每一個構造函數都擁有一個屬性(prototype),指向一個對象;
指向的這個對象中的屬性和方法,可以被所有該函數的實例所共享。
原型對象、構造函數、實例之間的關系
構造函數—》 原型對象:prototype
實例—>原型對象;proto
原型對象----》構造函數: constructor
原型鏈:(對象屬性和方法的調用)
對象查找屬性,首先會在當前對象中進行查找,如果找不到則會到對象的原型對象中去查找,
如果找不到則去原型對象的原型對象中去查找, 依次類推,這樣就形成了一個鏈式結構,
我們將其稱之為原型鏈
繼承:
1、類式繼承:子類的原型對象指向父類的實例
2、構造函數式繼承: 不是真正的繼承,在子類中使用父類的函數體,對對象進行簡化賦值
3、組合繼承: 1 + 2
4、寄生式繼承: 聲明一個空構造函數,將該函數的原型對象指向父類的原型對象
5、寄生組合式繼承: 2 + 4
1/*
2 原型:
3 每一個構造函數都擁有一個屬性(prototype),指向一個對象;
4 指向的這個對象中的屬性和方法,可以被所有該函數的實例所共享。
5 原型對象、構造函數、實例之間的關系
6 構造函數—》 原型對象:prototype
7 實例—>原型對象;proto
8 原型對象----》構造函數: constructor
9 原型鏈:(對象屬性和方法的調用)
10 對象查找屬性,首先會在當前對象中進行查找,如果找不到則會到對象的原型對象中去查找,
11 如果找不到則去原型對象的原型對象中去查找, 依次類推,這樣就形成了一個鏈式結構,
12 我們將其稱之為原型鏈
13*/
14/*
15 繼承:
16 1、類式繼承:子類的原型對象指向父類的實例
17 2、構造函數式繼承: 不是真正的繼承,在子類中使用父類的函數體,對對象進行簡化賦值
18 3、組合繼承: 1 + 2
19 4、寄生式繼承: 聲明一個空構造函數,將該函數的原型對象指向父類的原型對象
20 5、寄生組合式繼承: 2 + 4
21*/
22// 兩個類: 人類, 學生類
23// function Person(name, sex, age) {
24// this.name = name;
25// this.age = age;
26// this.sex= sex;
27// }
28// Person.prototype.show = function() {
29// console.log(111);
30// }
31
32// function Student(name, sex, age, grade) {
33// this.name = name;
34// this.age = age;
35// this.sex= sex;
36// this.grade = grade;
37// }
38
39// // 類式繼承
40// Student.prototype = new Person();
41// // 重新定義constructor
42// Student.prototype.constructor = Student;
43// // 給子類添加方法,必須在繼承之后
44// Student.prototype.say = function() {
45// console.log(222);
46// }
47
48
49
50// 構造函數式繼承
51
52// function Student(name, sex, age, grade) {
53// Person.apply(this, arguments)
54// this.grade = grade;
55// }
56// Student.prototype.say = function() {
57// console.log(222);
58// }
59
60// 組合繼承
61// 構造函數繼承
62// function Student(name, sex, age, grade) {
63// Person.apply(this, arguments)
64// this.grade = grade;
65// }
66// // 類式繼承
67// Student.prototype = new Person();
68// // 重新定義constructor
69// Student.prototype.constructor = Student;
70// // 給子類添加方法,必須在繼承之后
71// Student.prototype.say = function() {
72// console.log(222);
73// }
74
75// 寄生式繼承
76// function Person(name, sex, age) {
77// this.name = name;
78// this.age = age;
79// this.sex= sex;
80// }
81// Person.prototype.show = function() {
82// console.log(111);
83// }
84
85// function Student(name, sex, age, grade) {
86// this.name = name;
87// this.age = age;
88// this.sex= sex;
89// this.grade = grade;
90// }
91
92// // 創建一個空的構造函數
93// function F() {
94
95// }
96// // 該函數的原型對象指向父類的原型對象
97// F.prototype = Person.prototype;
98// // 子類的原型對象指向空函數的實例
99// Student.prototype = new F();
100// Student.prototype.constructor = Student;
101// Student.prototype.say = function() {
102// console.log(222);
103// }
104// 寄生組合式繼承
105function Person(name, sex, age) {
106 this.name = name;
107 this.age = age;
108 this.sex= sex;
109}
110Person.prototype.show = function() {
111 console.log(111);
112}
113
114function Student(name, sex, age, grade) {
115 Person.apply(this, arguments);
116 this.grade = grade;
117}
118
119// 創建一個空的構造函數
120function F() {
121
122}
123// 該函數的原型對象指向父類的原型對象
124F.prototype = Person.prototype;
125// 子類的原型對象指向空函數的實例
126Student.prototype = new F();
127Student.prototype.constructor = Student;
128Student.prototype.say = function() {
129 console.log(222);
130}
131
132
133
134
135var xiaoming = new Student(‘小明’, ‘男’, 18, 27);
136console.log(xiaoming);
137xiaoming.show();
138xiaoming.say();
四、安全類
無論new還是直接調用都產生對象
實例:
1function Student(name, sex) {
2 if (!(this instanceof Student)) {
3 return new Student(name, sex);
4 }
5 this.name = name;
6 this.sex = sex;
7}
8
五、垃圾回收機制和閉包
js的垃圾回收機制:
不用就刪掉
全局變量和局部變量
全局變量: 腳本運行結束
局部變量: 函數調用產生,函數調用結束消亡
閉包:延長局部變量聲明周期
思路:
1、延長一個變量聲明周期
2、聲明為一個全局變量
3、不想增加全局變量
4、讓全局變量引用局部變量
實現:
1、函數內存在局部變量
2、該局部變量被一個內部函數引用
3、函數的返回值為內部的函數
應用:
保護變量,只能使用對外提供的方式來訪問變量
實例:
1/* function xxoo() {
2 var a = 1;
3 function fun() {
4 console.log(++a);
5 }
6 return fun;
7}
8var res1 = xxoo();
9res1();
10res1(); */
11// function xxoo() {
12// var a = 1;
13// return function() {
14// console.log(++a);
15// }
16
17// }
18// var res1 = xxoo();
19// res1();// 2
20// res1();// 3
21
22// var res2 = xxoo();
23// res2();// 2
24// res2();// 3
25
26var res = (function() {
27 var a = 1;
28 return function() {
29 console.log(++a);
30 }
31
32})();
33res();
34res();
六、單例和閉包類
單例:
一個類只產生一個對象
在全局聲明一個類,則該類會被無限制的new,將類設計為閉包類
簡單單例:
在閉包中,直接實例化一個對象,該對象被外部所引用
缺陷:沒有按需實例化
惰性單例:
按需實例化
6.1 閉包類
將一個類封裝在一個閉包中
1var res = (function() {
2 function Student(name, sex, age) {
3 this.name = name;
4 this.sex = sex;
5 this.age = age;
6 }
7
8 return function() {
9 return Student;
10 }
11})();
6.2 普通單例
執行代碼:
1var res = (function() {
2 function Student(name, sex, age) {
3 this.name = name;
4 this.sex = sex;
5 this.age = age;
6 }
7
8 // 產生一個對象
9 var instance = new Student();
10
11 return function() {
12 // 返回對象
13 return instance;
14 }
15})();
16
17var obj1 = res();
18var obj2 = res();
19console.log(obj1, obj2);
20console.log(obj1 === obj2);
6.3 惰性單例
1var res = (function() {
2 function Student(name, sex, age) {
3 console.log(1111);
4 this.name = name;
5 this.sex = sex;
6 this.age = age;
7 }
8 // 產生一個對象
9 var instance = null;
10
11 return function(name, sex, age) {
12 // 判斷
13 if (!(instance instanceof Student)) {
14 instance = new Student();
15 }
16 // 設置對象的參數
17 instance.name = name;
18 instance.sex = sex;
19 instance.age = age;
20 // 返回對象
21 return instance;
22 }
23})();
24
25var obj1 = res(‘小明’, ‘男’, 18);
26console.log(obj1);
27var obj2 = res(‘莉莉’, ‘女’, 20);
28console.log(obj2);
29console.log(obj1 === obj2);
作業:
1// 需求: 在全局中只有一個namespace函數, 可以實現兩種功能, 一種是存儲數據,另一種是讀取數據
2 // 存儲數據的時候: namespace(‘a.b.c’, 123);
3 // 讀取數據的時候: namespace(‘a.b.c’) => 123
4 // 讀取: namespace(‘a.b’) => {c: 123}
5 // 讀取: namespace(‘a’) => {b: {c: 123}}
6 // {
7 // b: {
8 // c: 123
9 // }
10 // }
11
12
13 // 該函數可以實現兩種功能:
14 // 第一種是可以存儲數據: 當存儲數據的時候需要接受兩個參數,第一個參數是存儲的路徑,第二個參數存儲的數據
15 // 第二種是可以讀取數據: 當讀取數據的時候,需要接受一個參數就是要讀取的路徑
16
總結
以上是生活随笔為你收集整理的对于javaScript设计模式的认知与学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html中的src路径怎么写,HTML
- 下一篇: 北航 2018计算机学院排课,关于201