1、特点
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换
2、demo
使用策略模式计算奖金
//策略模式
//策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
//使用策略模式计算奖金
var calculateBonus = function(performanceLevel, salary) {
if (performanceLevel === 'S') {
return salary * 4;
}
if (performanceLevel === 'A') {
return salary * 3;
}
if (performanceLevel === 'B') {
return salary * 2;
}
};
calculateBonus('B', 2000);
calculateBonus('S', 6000);
//使用策略模式计算奖金 优化
var performanceS = function() {};
performanceS.prototype.calculate = function(salary) {
return salary * 4;
};
var performanceA = function() {};
performanceA.prototype.calculate = function(salary) {
return salary * 4;
};
var performanceB = function() {};
performanceB.prototype.calculate = function(salary) {
return salary * 4;
};
var Bonus = function() {
this.salary = null; //原始工资
this.strategy = null; //绩效等级对应的策略对象
};
Bonus.prototype.setSalary = function(salary) {
this.salary = salary;
};
Bonus.prototype.setStrategy = function(strategy) {
this.strategy = strategy;
};
Bonus.prototype.getBonus = function() {
return this.strategy.calculate(this.salary);
};
var bonus = new Bonus();
bonus.setSalary(10000);
bonus.setStrategy(new performanceS());
console.log(bonus.getBonus());
bonus.setStrategy(new performanceA());
console.log(bonus.getBonus());
// JavaScript 版本的策略模式
var strategies = {
"S": function(salary) {
return salary * 4
},
"A": function(salary) {
return salary * 3;
},
"B": function(salary) {
return salary * 2;
}
};
var calculateBonus = function(level, salary) {
return strategies[level](salary);
};
console.log(calculateBonus('S', 2000));
console.log(calculateBonus('A', 1000));
小球的运动动画
<html>
<body>
<div style="position:absolute;background:blue;
width: 10px;
height: 10px;
border-radius: 100%;" id="div">
</div>
</body>
<script>
var tween = {
linear: function(t, b, c, d) {
return c * t / d + b;
},
easeIn: function(t, b, c, d) {
return c * (t /= d) * t + b;
},
strongEaseIn: function(t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
strongEaseOut: function(t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
sineaseIn: function(t, b, c, d) {
return c * (t /= d) * t * t + b;
},
sineaseOut: function(t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
}
};
var animate = function(dom) {
this.dom = dom; //进行运动的dom节点
this.startTime = 0; //动画开始时间
this.startPos = 0; // 动画开始时,dom节点的位置,即dom的初始位置
this.endPos = 0; //动画结束时,dom节点的位置,即dom的目标位置
this.propertyName = null; //dom节点需要被改变的css属性名
this.easing = null; //暖动算法
this.duration = null; //动画持续时间
}
//propertyName:要改变的CSS 属性名,比如'left'、'top',分别表示左右移动和上下移动。
//endPos: 小球运动的目标位置
//duration: 动画持续时间
//easing: 缓动算法
animate.prototype.start = function(propertyName, endPos, duration, easing) {
this.startTime = +new Date; //动画启动时间
this.startPos = this.dom.getBoundingClientRect()[propertyName]; // dom 节点初始位置
this.propertyName = propertyName;
this.endPos = endPos; //dom节点目标位置
this.duration = duration; //动画持续事件
this.easing = tween[easing]; //暖动算法
var self = this;
var timeId = setInterval(function() { //启动定时器,开始执行动画
if (self.step() === false) { //如果动画结束,则清除定时器
clearInterval(timeId);
// self.update(0);
// this.startTime = new Date;
}
}, 20);
};
animate.prototype.step = function() {
var t = +new Date;
if (t >= this.startTime + this.duration) {
this.update(this.endPos); //更新小球的css属性值
return false;
}
var pos = this.easing(t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration);
//pos为小球当前位置
this.update(pos); //更新小球的css属性值
};
animate.prototype.update = function(pos) {
this.dom.style[this.propertyName] = pos + 'px';
};
var div = document.getElementById('div');
var animate = new animate(div);
animate.start('left', 500, 1000, 'strongEaseOut');
animate.start('left', 500, 1000, 'strongEaseIn');
</script>
</html>
参考文献:《JavaScript设计模式与开发实践》