在JavaScript中函数也是一个对象,那么对象中就可以有属性和方法。
属性name
:一个函数的名词我们可以通过name来访问;function foo(){
}
console.log(foo.name)/ /foo
var bar = function() {
}
console.log(bar.name)//bar
属性length
:属性length用于返回函数参数的个数;注意: rest参数是不参与参数的个数的; var baz = (name,age, ...args) =>{
}
console.log(baz.length)
arguments是一个对应于传递给函数的参数的类数组(array-like)对象。
array-like意味着它不是一个数组类型,而是一个对象类型:
console.log(arguments.length)
console.log(arguments[0]
console.log(arguments[1])
console.log(arguments[2])
在开发中,经常需要将arguments转成Array,以便使用数组的一些特性。常见的转化方式如下 :
箭头函数是不绑定arguments的,所以在箭头函数中使用arguments会去上层作用域查找:
ES6中引用了rest parameter,可以将不定数量的参数放入到一个数组中:
function foo(m, n, ...args){
console.log(m, n)
console.log(args)
}
没有对应形参的实参
,而 arguments对象包含了传给函数的所有实参
;arguments对象不是一个真正的数组
,而rest参数是一个真正的数组
,可以进行数组的所有操作;早期的ECMAScript
中为了方便去获取所有的参数提供的一个数据结构,而rest参数是ES6中提供
并且希望以此来替代arguments的;剩余参数必须放到最后一个位置,否则会报错。
react中组件就被要求像是一个纯函数
(为什么是像,因为还有class组件),redux中有一个reducer的概念
,也是要求必须是一个纯函数
;在程序设计中,若一个函数符合以下条件
,那么这个函数被称为纯函数:
在相同的输入值时
,需产生相同的输出
。输出和输入值以外的其他隐藏信息或状态无关
,也和由I/O设备产生的外部输出无关
。不能有语义上可观察的函数副作用
,诸如“触发事件”
,使输出设备输出,或更改输出值以外物件的内容
等。总结:确定的输入,一定会产生确定的输出;函数在执行过程中,不能产生副作用;
副作用解释:
在计算机科学中,也引用了副作用的概念,表示在执行一个函数时,除了返回函数值之外,还对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者改变外部的存储;
以对数组操作的两个函数为例:
slice
: slice截取数组时不会对原数组进行任何操作,而是生成一个新的数组; splice
: splice截取数组,会返回一个新的数组,也会对原数组进行修改;slice就是一个纯函数,不会修改数组本身,而splice函数不是一个纯函数;
var names =[ "abc" , "cba" , "nba" , "dna"]
// slice截取数组时不会对原数组进行任何操作,而是生成一个新的数组
var newNames =names.slice(0,2)
console.log (newNames)
//splice截取数组,·会返回一个新的数组,也会对原数组进行修改
var newNames2 = names.splice(0,2)
console.log(newNames2)
console.log(names)
纯函数的优势:
(1)代码阅读性提高
(2)提高了代码的复用性
(3)IO简单,测试简单
(4)可作缓存或记忆功能
- 可以安心的编写和安心的使用;
- 在写的时候保证了函数的纯度,只是单纯实现自己的业务逻辑即可,不需要关心传入的内容是如何获得的或者依赖其他的外部变量是否已经发生了修改;
- 用的时候,只需要确定输入内容不会被任意篡改,并且自己确定的输入,一定会有确定的输出;
柯里化也是属于函数式编程里面一个非常重要的概念。
维基百科的解释:
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化:
接收多个参数
的函数,变成接收一个单一参数
(最初函数的第一个参数)的函数,并且返回接收余下的参数
,而且返回结果的新函数
的技术;理解总结:
只传递给函数一部分参数来调用它
,让它返回一个函数去处理剩余的参数
。这个过程就称之为柯里化
;
柯里化是一种函数的转换,将一个函数从可调用的f(a, b, d)转换为可调用的f(a)(b)(d)。口柯里化不会调用函数。它只是对函数进行转换。
柯里化过程代码示例:
//未柯里化的函数
function add1(x,y,z){
return X +y +z
}
console.log(add1(10,20,30))
//柯里化处理的函数
function add2(x){
return function(y){
return function(z){
return x +y +z
}
}
}
console.log(add2 (10) (20)(30))
//使用箭头函数优化
var add3 = × => y => z =>{
return x +y+z
}
console.log (add3 (10)(20) (30))
//var foo3 = X =>y=>Z=>console.log(x +y + z)
组合(Compose)函数是在JavaScript开发过程中一种对函数的使用技巧、模式:
需要对某一个数据进行函数的调用
,执行两个函数
fn1和fn2,这两个函数是依次执行
的;如果每次都需要进行两个函数的调用
,操作
上就会显得重复
;组合通用函数的封装(了解):
function hyCompose(...fns) {
var length = fns.length
for (var i = 0; i < length; i++) {
if (typeof fns[i] !== 'function') {
throw new TypeError("Expected arguments are functions")
}
}
function compose(...args) {
var index = 0
var result = length ? fns[index].apply(this, args): args
while(++index < length) {
result = fns[index].call(this, result)
}
return result
}
return compose
}
function double(m) {
return m * 2
}
function square(n) {
return n ** 2
}
var newFn = hyCompose(double, square)
console.log(newFn(10))