设计模式
2022年9月29日大约 3 分钟
设计模式
多态
多态
一词源于希腊文 polymorphism,拆开来看是 poly(复数)+ morph(形态)+ ism,
从字面上我们可以理解为复数形态。
多态的实际含义是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结
果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的
反馈。
多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事
物”与 “可能改变的事物”分离开来。
动物都会叫,这是不变的,但是不同类型的动物具体怎么叫是可变的。把不变的部分隔离出来,把可变的部分封装起来,这给予了我们扩展程序的能力,程序看起来是可生长的,也是符合开放—封闭原则的,相对于修改代码来说,仅仅增加代码就能完成同样的功能,这显然优雅和安全得多。
var makeSound = function( animal ){
animal.sound();
};
var Duck = function(){}
Duck.prototype.sound = function(){
console.log( '嘎嘎嘎' );
};
var Chicken = function(){}
Chicken.prototype.sound = function(){
console.log( '咯咯咯' );
};
makeSound( new Duck() );
// 嘎嘎嘎
makeSound( new Chicken() );
// 咯咯咯
// 如果有一天动物世界里又增加了一只狗,这时候只要简单地追加一些代码就可以了
var Dog = function(){}
Dog.prototype.sound = function(){
console.log( '汪汪汪' );
};
makeSound( new Dog() );
// 汪汪汪
高阶函数
高阶函数是指至少满足下列条件之一的函数。
- 函数可以作为参数被传递;
- 函数可以作为返回值输出。
回调函数
// 把 callback 函数当作参数传入 发起 ajax 请求的方法中,待请求完成之后执行 callback 函数:
var getUserInfo = function( userId, callback ){
$.ajax( 'http://xxx.com/getUserInfo?' + userId, function( data ){
if ( typeof callback === 'function' ){
callback( data );
}
});
}
getUserInfo( 13157, function( data ){
alert ( data.userName );
});
1.2 Array.prototype.sort
Array.prototype.sort 接受一个函数当作参数,这个函数里面封装了数组元素的排序规则
//从小到大排列
[ 1, 4, 3 ].sort( function( a, b ){
return a - b;
});
// 输出: [ 1, 3, 4 ]
//从大到小排列
[ 1, 4, 3 ].sort( function( a, b ){
return b - a;
});
// 输出: [ 4, 3, 1 ]
函数作为返回值输出
var isType = function( type ){
return function( obj ){
return Object.prototype.toString.call( obj ) === '[object '+ type +']';
}
};
var isString = isType( 'String' );
var isArray = isType( 'Array' );
var isNumber = isType( 'Number' );
console.log( isArray( [ 1, 2, 3 ] ) );
// 输出:true
高阶函数实现AOP
AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些
跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后,
再通过“动态织入”的方式掺入业务逻辑模块中。这样做的好处首先是可以保持业务逻辑模块的纯净和高内聚性,其次是可以很方便地复用日志统计等功能模块。
// 通常,在 JavaScript 中实现 AOP,都是指把一个函数“动态织入”到另外一个函数之中,具体的实现技术有很多,
Function.prototype.before = function( beforefn ){
var __self = this;
// 保存原函数的引用
return function(){ // 返回包含了原函数和新函数的"代理"函数
beforefn.apply( this, arguments );
// 执行新函数,修正 this
return __self.apply( this, arguments );
// 执行原函数
}
};
Function.prototype.after = function( afterfn ){
var __self = this;
return function(){
var ret = __self.apply( this, arguments );
afterfn.apply( this, arguments );
return ret;
}
};
var func = function(){
console.log( 2 );
};
func = func.before(function(){
console.log( 1 );
}).after(function(){
console.log( 3 );
});
func();
// 1
// 2
// 3