javascript设计模式与实践-笔记

函数柯里化

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中要好。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值