惰性函数
常用于函数库的编写,单例模式中
// 惰性函数
function addEvent(dom, type, handler) {
if (dom.addEventListener) {
console.log('first')
dom.addEventListener(type, handler, false)
// 这里结合预编译的过程
addEvent = function(dom, type, handler) {
console.log('last')
dom.addEventListener(type, handler, false)
}
} else {
dom.attachEvent('on' + type, handler)
addEvent = function(dom, type, handler) {
dom.attachEvent('on' + type, handler)
}
}
}
addEvent(btn, 'click', function() {
alert('ccx')
})
addEvent(btn, 'click', function() {
alert('ccx1')
})
数据扁平化
最基本的处理方法,这些方法还没考虑到如果数组中包含着对象应该如何解决
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]'
}
var arr1 = [3,[3,[3]]]
function flatten(arr) {
var arr = arr || [],
resArr = [],
len = arr.length;
for(var i = 0; i < len; i ++) {
if (isArray(arr[i])) {
resArr = resArr.concat(flatten(arr[i]))
} else {
resArr.push(arr[i])
}
}
return resArr
}
运用forEach(item, index)进行遍历
Array.prototype.flatten = function() {
var resArr = []
this.forEach(function(item) {
Object.prototype.toString.call(item) == '[object Array]' ? resArr = resArr.concat(item.flatten()) : resArr.push(item)
})
return resArr
}
函数式编程纯函数
纯函数是指不依赖,修改其作用域之外变量的函数,可遇不可求
// 这个函数依赖了外部变量num
var num = 10
function compare(x) {
return x > num
}
记忆函数
提高效率,减少执行时间
function factorial(n) {
if(n == 1 || n == 0) {
return 1
} else {
return n * factorial(n - 1)
}
}
function memorize(fn) {
var cache = {}
return function() {
var key = arguments.length + Array.prototype.join.call(arguments)
console.log(key)
console.log(Array.prototype.join.call(arguments))
if(cache[key]) {
return cache[key]
} else {
cache[key] = fn.apply(this, arguments)
return cache[key]
}
}
}
var newF = memorize(factorial)
console.time()
console.log(newF(5))
console.timeEnd()
console.time()
console.log(newF(5))
console.timeEnd()
函数柯里化
为什么要实现柯里化
前段使用柯里化的用途主要是简化代码结构,提高系统的维护性,一个方法只有一个参数,强制了功能的单一性,很自然做到了功能内聚,降低耦合。
优点就是:降低代码的重复,提高代码的适应性
调用的形式
function add(a, b, c) {}
var newAdd = Curry(add)
newAdd(2)(3)(3)
代码的实现
function add(a, b, c, d) {
return a + b + c + d
}
function FixParmasCurry(fn) {
// 这里截取的是fn后面的参数
var _arg = [].slice.call(arguments, 1)
console.log(_arg)
return function() {
var newArg = _arg.concat([].slice.call(arguments, 0))
return fn.apply(this, newArg) // this绑定的就是add,也固定了应该传进来的参数
}
}
var newAdd = FixParmasCurry(add, 1, 2)
newAdd(2, 3)
function add(a, b, c, d) {
return a + b + c + d
}
function FixParmasCurry(fn) {
// 这里截取的是fn
var _arg = [].slice.call(arguments, 1)
return function() {
var newArg = _arg.concat([].slice.call(arguments, 0))
return fn.apply(this, newArg) // this绑定的就是add
}
}
function Curry(fn, length) {
// 应该传的参数个数
var length = length || fn.length
return function () {
if (arguments.length < length) {
[fn, 3, 3, 3]
var combined = [fn].concat([].slice.call(arguments, 0))
return Curry(FixParmasCurry.apply(this, combined), length - arguments.length)
} else {
return fn.apply(this, arguments)
}
}
}
var newAdd = Curry(add)
var a = newAdd(3,3,3)(3)