惰性函數
常用於函數庫的編寫,單例模式中
// 惰性函數
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)