设计模式其实就是以前别人写代码的一些套路
可以满足某一类的使用场景
优点:
- 可维护性好
- 便于沟通
性能
缺点:
- 复杂性
- 性能
1. 对象
原始代码
function startAnimation() {
console.log('start animation')
}
function stopAnimation() {
console.log('stop animation')
}
改为面向对象的方式
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')
}
}
持续改进
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')
})
持续改进,链式调用
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')
})
匿名函数
以下是立即执行的函数表达式
(function(){
var foo = 1
var bar = 2
console.log(foo * bar)
})()
携带参数
(function(foo, bar){
console.log(foo * bar)
})(1, 2)
var a = function(foo, bar){
console.log(foo * bar)
}
a(1,2)
闭包,访问函数内部的局部变量
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('设计模式')
myBook.display()
myBook.checkTitle('啊') //不希望这个方法被外部调用,只希望被内部调用
myBook.title = 'Http深入浅出' //不希望直接修改这个属性
在使用上面的方法时, 调用者在调用时可能不会使用checkTitle去设置而是直接改变title的值
解决方法
形式上的“封装”
给不想暴露的方法命名加下划线,虽然本质上没什么用,但至少形式上便于理解
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 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('设计模式')
myBook.display()
静态方法和属性
更高级的写法
var Book = (function() {
//私有的静态变量,只有一份
var numOfBooks = 0
//私有的静态方法,只有一份
function checkTitle(title) {
return title.length > 2 && title.length < 20
}
return function() {
var title
numOfBooks++
if(numOfBooks > 10) throw new Error('最多只能创建10本书')
this.setTitle = function(newTitle) {
if(!checkTitle(newTitle)) return
title = newTitle
}
this.display = function() {
console.log('Book title is ' + title)
}
}
})()
//公开的静态方法
Book.convertToTitlecase = function(str) {}
//公开的实例方法
Book.prototype = {
other: function(){}
}