函数柯里化
1、currying个人理解
概念:一个currying的函数首先会接受一些承诺书,接受了这些参数之后,该函数并不会立即求职,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求职
var cost = (function){
var args = [];
return function(){
if(arguments.length === 0 ){
var money = 0;
for ( var i = 0,l = args.length; i <= l; i++) {
money += args[i]
}
return money;
} else {
[].push.apply(args, arguments)
}
}
}()
// 通用的currying
var currying = function ( fn ) {
var args = [];
return function () {
if (arguments.length === 0) {
console.log(args)
return fn.apply(this, args)
} else {
[].push.apply(args, arguments)
return arguments.callee;
}
}
}
var cost = (function(){
var money = 0;
return function() {
for (i = 0; i<arguments.length;i++){
money += arguments[i];
}
return money;
}
})()
var cost = currying(cost);
cost(100)
cost(100)
cost(100)
cost(100)
cost(100)
cost() // 结果累加
单例模式
学完单例模式 感觉最重要的就是
if(存在的某个元素or变量){
return 存在某个元素or变量
}
创建第一次进来的元素or变量
下面是惰性单例模式
var getSingle = function( fn ) {
var result;
return function () {
return result || (result = fn.apply(this, arguments))
}
}
var createLoginLayer = function() {
创建变量或者元素逻辑
return 变量或者元素
}
var createSingleLoginLayer = getSingle( createLoginLayer )
策略模式
小球滚动动画算法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小球teween</title>
</head>
<body>
<div style="position: absolute;background:blue;width: 50px;height:50px;border-radius: 50%;"></div>
</body>
</html>
<script>
var tween = {
Linear: function (t, b, c, d) { return c * t / d + b; },
Quad: {
easeIn: function (t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOut: function (t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOut: function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
},
Cubic: {
easeIn: function (t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOut: function (t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
},
easeInOut: function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
}
}
}
var Animate = function (dom) {
this.dom = dom
this.startTime = 0
this.startPos = 0
this.endPos = 0
this.propertyName = null
this.easing = null
this.duration = null
}
Animate.prototype.start = function (propertyName, endPos, duration, easing, children) {
try {
this.startTime = +new Date()
this.startPos = this.dom.getBoundingClientRect()[propertyName]
this.endPos = endPos
this.duration = duration
this.propertyName = propertyName
this.easing = tween[easing][children] || tween[easing]
} catch (error) {
console.log(error)
}
var self = this
var timeId = setInterval(function () {
if (self.step() === false) {
clearInterval(timeId)
}
}, 19) // 19毫秒每帧是刚刚好的效果
}
Animate.prototype.step = function () {
var t = +new Date()
if (t >= this.startTime + this.duration) {
this.update(this.endPos)
return false
}
try {
var pos = this.easing(t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration)
} catch (error) {
console.log(this.easing)
alert('小球没有定义运动规则')
return false
}
this.update(pos)
}
Animate.prototype.update = function (pos) {
this.dom.style[this.propertyName] = `${pos}px`
}
var div = document.getElementsByTagName('div')[0]
var animate = new Animate(div)
animate.start('left', 500, 500, 'Cubic', 'easeIn')
</script>
策略模式的本质就是把很多的if-else给省略掉,如果你是几个if-else 尽管用即可
策略模式的优缺点
优点:
- 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。
- 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的strategy中,使得他们易于切换,易于理解,易于拓展。
- 策略模式中的算法也可以服用在系统的其他地方,从而避免许多重复的复制粘贴工作。
- 在策略模式中利用组合和委托来让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。
缺点:
- 使用策略模式会在程序中增加许多策略类或者策略对象,但实际上这比把它们负责的逻辑堆砌在Context中要好。