設(shè)計模式其實(shí)就是以前別人寫代碼的一些套路
可以滿足某一類的使用場景
優(yōu)點(diǎn):
- 可維護(hù)性好
- 便于溝通
性能
缺點(diǎn):
- 復(fù)雜性
- 性能
1. 對象
原始代碼
function startAnimation() {
console.log('start animation')
}
function stopAnimation() {
console.log('stop animation')
}
改為面向?qū)ο蟮姆绞?/p>
var Anim = function() {
}
Anim.prototype.start = function() {
console.log('start animation')
}
Anim.prototype.stop = function() {
console.log('stop animation')
}
var myAnim = new Anim()
myAnim.start()
myAnim.stop()
變形簡化
var Anim = function() {}
Anim.prototype = {
start: function() {
console.log('start')
},
stop: function() {
console.llog('end')
}
}
持續(xù)改進(jìn)
Function.prototype.method = function(name, fn) {
this.prototype[name] = fn
}
var Anim = function() {
}
Anim.method('start', function() {
console.log('start animation')
})
Anim.method('stop', function() {
console.log('stop animation')
})
持續(xù)改進(jìn),鏈?zhǔn)秸{(diào)用
Function.prototype.method = function(name, fn) {
this.prototype[name] = fn
return this
}
var Anim = function() {}
Anim.method('start', function() {
console.log('start animation')
}).method('stop', function() {
console.log(stop animation')
})
匿名函數(shù)
以下是立即執(zhí)行的函數(shù)表達(dá)式
(function(){
var foo = 1
var bar = 2
console.log(foo * bar)
})()
攜帶參數(shù)
(function(foo, bar){
console.log(foo * bar)
})(1, 2)
var a = function(foo, bar){
console.log(foo * bar)
}
a(1,2)
閉包,訪問函數(shù)內(nèi)部的局部變量
var baz
(function(){
var foo = 1
var bar = 2
baz = function() {
return foo * bar
}
})()
baz()
2.封裝
JS對象沒有私有屬性
var Book = function() {
}
Book.prototype.setTitle = function(title) {
if(!this.checkTitle(title)) return
this.title = title
}
Book.prototype.checkTitle = function(title) {
return title.length > 2 && title.length < 20
}
Book.prototype.display = function() {
console.log('Book title is ' + this.title)
}
var myBook = new Book()
myBook.setTitle('設(shè)計模式')
myBook.display()
myBook.checkTitle('啊') //不希望這個方法被外部調(diào)用,只希望被內(nèi)部調(diào)用
myBook.title = 'Http深入淺出' //不希望直接修改這個屬性
在使用上面的方法時, 調(diào)用者在調(diào)用時可能不會使用checkTitle去設(shè)置而是直接改變title的值
解決方法
形式上的“封裝”
給不想暴露的方法命名加下劃線,雖然本質(zhì)上沒什么用,但至少形式上便于理解
var Book = function() {
}
Book.prototype.setTitle = function(title) {
if(!this._checkTitle(title)) return
this.title = title
}
Book.prototype._checkTitle = function(title) {
return title.length > 2 && title.length < 20
}
Book.prototype.display = function() {
console.log('Book title is ' + this.title)
}
讓需要隱藏的數(shù)據(jù)變?yōu)榫植孔兞?/strong>
var Book = function() {
var title
function checkTitle(title) {
return title.length > 2 && title.length < 20
}
this.setTitle = function(newTitle) {
if(!checkTitle(newTitle)) return
title = newTitle
}
this.display = function() {
console.log('Book title is ' + title)
}
}
Book.prototype.other = function() {}
var myBook = new Book()
myBook.setTitle('設(shè)計模式')
myBook.display()
靜態(tài)方法和屬性
更高級的寫法
var Book = (function() {
//私有的靜態(tài)變量,只有一份
var numOfBooks = 0
//私有的靜態(tài)方法,只有一份
function checkTitle(title) {
return title.length > 2 && title.length < 20
}
return function() {
var title
numOfBooks++
if(numOfBooks > 10) throw new Error('最多只能創(chuàng)建10本書')
this.setTitle = function(newTitle) {
if(!checkTitle(newTitle)) return
title = newTitle
}
this.display = function() {
console.log('Book title is ' + title)
}
}
})()
//公開的靜態(tài)方法
Book.convertToTitlecase = function(str) {}
//公開的實(shí)例方法
Book.prototype = {
other: function(){}
}