函数式编程(Functional Programming,后面简称FP),维基百科的定义是:
是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数编程语言最重要的基础是λ演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。比起命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。
我来尝试理解下这个定义,好像就是说,在敲代码的时候,我要把过程逻辑写成函数,定义好输入参数,只关心它的输出结果。而且可以把函数作为输入输出。感觉好像平常写js时,就是这样的嘛!
网上FP的定义与特性琳琅满目。各种百科、博客、一些老师的网站上都有大同小异的介绍。为了方便阅读,我列下几个好像比较重要的特性,并附上我的第一眼理解。
函数是一等公民。就是说函数可以跟其他变量一样,可以作为其他函数的输入输出。喔,回调函数就是典型应用。
不可变量。就是说,不能用var跟let咯。按这要求,我似乎有点难写代码。
纯函数。就是没有副作用的函数。这个好理解,就是不修改函数外部的变量。
引用透明。这个也好理解,就是说同样的输入,必定是同样的输出。函数内部不依赖外部状态,如一些全局变量。
惰性计算。大意就是:一个表达式绑定的变量,不是声明的时候就计算出来,而是真正用到它的时候才去计算。
var animals = [
{name:'Fluffykins',species:'rabbit'},
{name:'Caro',species:'dog'},
{name:'Hamilton',species:'dog'},
{name:'Harold',species:'fish'},
{name:'Ursula',species:'cat'},
{name:'Jimmy',species:'fish'}
]
//第一种做法
var dogs = []
for (var i = 0; i < animals.length; i++){
if(animals[i].species === 'dog'){
dog.push(animals[i])
}
}
//第二种做法
var dogs = animals.filter(function(animal){
return animal.species === 'dog'
})
//优化
let isDog = unction(animal){
return animal.species === 'dog'
}
var dogs = animals.filter(isDog)
var animals = [
{name:'Fluffykins',species:'rabbit'},
{name:'Caro',species:'dog'},
{name:'Hamilton',species:'dog'},
{name:'Harold',species:'fish'},
{name:'Ursula',species:'cat'},
{name:'Jimmy',species:'fish'}
]
//第一种做法
var names = []
for ( var i = 0 ; i < animals.length; i++){
names.push(animals[i].name)
}
//第二种做法
var names = animals.map(function(animal){
return animal.name
})
//优化
var names = animals.map((animal) => animal.name)
var orders = [
{amount:250},
{amount:400},
{amount:100},
{amount:325}
]
//第一种做法
var totalAmount = 0
for ( var i = 0; i < orders.length; i++){
totalAmount = orders[i].amount
}
//第二种做法
var totalAmount = orders.reduce(function(sum,order){
return sum + order.amount
},0)
//优化
var totalAmount = orders.reduce((sum,order) => sum + order.amount
},0)
let dragon = (name,size,element) =>
`${name} is a ${size} dragon that breathes ${element} !`
console.log(dragon('fluffykins','tiny','lightling'))
//curry
let dragon =
name =>
size =>
element =>
`${name} is a ${size} dragon that breathes ${element} !`
console.log(dragon('fluffykins')('tiny')('lightling'))
//还可以
let dragon =
name =>
size =>
element =>
`${name} is a ${size} dragon that breathes ${element} !`
let fluffykinDragon = dragon('fluffykins')
console.log(fluffykinDragon('tiny')('lightling'))
//甚至是这样
let dragon =
name =>
size =>
element =>
`${name} is a ${size} dragon that breathes ${element} !`
let fluffykinDragon = dragon('fluffykins')
let tinyDragon = fluffykinDragon('tiny')
console.log(tinyDragon('lightling'))
//使用lodash
import _ from 'lodash'
let dragon =(name,size,element) => (
`${name} is a ${size} dragon that breathes ${element} !`
)
dragon = _.curry(dragon)
let fluffykinDragon = dragon('fluffykins')
let tinyDragon = fluffykinDragon('tiny')
console.log(tinyDragon('lightling'))
let dragons = [
{name:'fluffykins',element:'lightning'},
{name:'nomi',element:'lightning'},
{name:'karo',element:'fire'},
{name:'doomer',element:'timewrap'},
]
let hasElement = (element,obj) => obj.element === element
let lightingDragons = dragons.filter(x => hasElement('lightning',x)
console.log(lightingDragons)
//使用loadash_curry改造
import _ from 'lodash'
let hasElement = _.curry(element,obj) => obj.element === element
let lightingDragons = dragons.filter(hasElement('lightning'))
console.log(lightingDragons)
let categories = [
{
id:'animals',
'parent':null
},
{
id:'mammals',
'parent':'animals'
},
{
id:'cats',
'parent':'mammals'
},
{
id:'dogs',
'parent':'mammals'
},
{
id:'chihuahua',
'parent':'dogs'
},
{
id:'labrador',
'parent':'dogs'
},
{
id:'persian',
'parent':'cats'
},
{
id:'siamese',
'parent':'cats'
}
]
let makeTree = (categories,parent) => {
let node = {
}
categories.filter(c => c.parent === parent)
.forEach(c =>
node[c.id] = makeTree(categories,c.id))
return node
}
console.log(
JSON.stringify(
makeTree(categories,null)
,null
,2
)
)
我理解的 JavaScript 函数式编程,都认为属于函数式编程的范畴,只要他们是以函数作为主要载体的。
给你的代码增加一点点函数式编程的特性,最近我对函数式编程非常感兴趣。这个概念让我着迷:应用数学来增强抽象性和强制纯粹性,以避免副作用,并实现代码的良好可复用性。同时,函数式编程非常复杂。
Async/await以及它底层promises的应用正在猛烈地冲击着JS的世界。在大多数客户端和JS服务端平台的支持下,回调编程已经成为过去的事情。当然,基于回调的编程很丑陋的。
如果你曾经了解或编写过JavaScript,你可能已经注意到定义函数的方法有两种。即便是对编程语言有更多经验的人也很难理解这些差异。在这篇博客的第一部分,我们将深入探讨函数声明和函数表达式之间的差异。
随着软件应用的复杂度不断上升,为了确保应用稳定且易拓展,代码质量就变的越来越重要。不幸的是,包括我在内的几乎每个开发者在职业生涯中都会面对质量很差的代码。这些代码通常有以下特征:
在js开发中,程序代码是从上而下一条线执行的,但有时候我们需要等待一个操作结束后,再进行下一步操作,这个时候就需要用到回调函数。 在js中,函数也是对象,确切地说:函数是用Function()构造函数创建的Function对象。
这篇文章主要介绍ES5中函数的4种调用,在ES5中函数内容的this指向和调用方法有关。以及ES6中函数的调用,使用箭头函数,其中箭头函数的this是和定义时有关和调用无关。
函数的三种定义方法分别是:函数定义语句、函数直接量表达式和Function()构造函数的方法,下面依次介绍这几种方法具体怎么实现,在实际编程中,Function()构造函数很少用到,前两中定义方法使用比较普遍。
微软 称excel就实现面向开发者的功能,也就是说我们不仅可以全新定义的公式,还可以重新定义excel的内置函数,现在Excel自定义函数增加了使用 JavaScript 编写的支持,下面就简单介绍下如何使用js来编写excel自定义函数。
这篇文章主要讲解:js立即执行函数是什么?js使用立即执行函数有什么作用呢?js立即执行函数的写法有哪些?
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!