柯里化,高阶函数

2019-05-10  本文已影响0人  栗子daisy

柯里化:多参数函数变成接受单一参数并将【接受余下参数返回结果的】新函数返回的技术。

let add =(a,b)=>a+b
add(1,2) //3
// 正常写法,需要传递两个参数给add
 add(1) // NAN(缺少一个参数)

柯里化-es6--延迟参数传递,参数复用

let add = a=>b=>a+b
add(1)(2)//3 
// 柯里化写法,将参数变换成一个,延迟函数参数的传入
 add(1) // function(b) {return a+ b}

柯里化-es5写法

let add = function(a){
  return function(b){
    return a+b
  }
}
add(1)(2)//3 

函数柯里化基本是在做这么一件事情:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
假如一个函数只能收一个参数,那么这个函数怎么实现加法呢,因为高阶函数是可以当参数传递和返回值的,所以问题就简化为:写一个只有一个参数的函数,而这个函数返回一个带参数的函数,这样就实现了能写两个参数的函数了(具体参见下边代码)——这就是所谓的柯里化(Currying,以逻辑学家Hsakell Curry命名),也可以理解为一种在处理函数过程中的逻辑思维方式。

高阶函数: 满足下列条件之一的函数:

  • 函数作为参数被传递;(如回调函数)
  • 函数作为返回值输出;(如柯里化)
function add (x,y,f){
  return f(x) + f(y)
}
add(5,6,Math.abs) =>11
// 接收了函数f,并且把x,y参数传到函数f中

// es6写法

let add2 = (x,y,f) => f(x)+f(y)
console.log(add2(-1,5,Math.abs)) =>6

eg.过滤

let users = [
  { name: 'Qian', age: 27, pets : ['Bao'], title : 'Consultant' },
  { name: 'Zeynep', age: 19, pets : ['Civelek', 'Muazzam'] },
  { name: 'Yael', age: 52, title : 'VP of Engineering'}
];

普通实现

let result = users
  .filter(x => x.hasOwnProperty('pets'))
  .sort((a, b) => a.age > b.age);
//过滤出有宠物和有职位的用户
let result2 = users
  .filter(x => x.hasOwnProperty('pets'))
  .filter(x => x.hasOwnProperty('title'))

高阶函数

const has = p => o => o.hasOwnProperty(p);
const sortBy = p => (a, b) => a[p] > b[p];

result = users.filter(has('pets')).sort(sortBy('age'))
//过滤出有宠物和有职位的用户
result2 = users.filter(has('pets')).filter(has('title'))
const hasPets = has('pets');//过滤出有宠物的用户
const isEmployed = has('title');//有职位的用户
const byAge = sortBy('age');

let workers = users.filter(isEmployed);
let petOwningWorkers = workers.filter(hasPets);
let workersByAge = workers.sort(byAge);
let user = {name: 'Assata', age: 68, title: 'VP of Operations'};
if(isEmployed(user)){   // true
  //do employee action
}
hasPets(user);          // false
has('age')(user);       //true

写一个能检查对象拥有一个有固定值的主键的过滤函数

const is = prop => val => obj => has(prop)(obj) && obj[prop] == val;
// broken down:
// outer:  prop => [inner1 function, uses prop]
// inner1: val => [inner2 function, uses prop and val]
// inner2: oobj => obj.hasOwnProperty(prop) && obj[prop] = val;

用is函数来过滤用户的示例:

const titleIs = is('title');
// titleIs == v => o => o.hasOwnProperty('title') && o['title'] == v;

const isContractor = titleIs('Contractor');
// isContractor == o => o.hasOwnProperty('contractor') && o['title'] == 'Contractor';

let contractors = users.filter(isContractor);
let developers  = users.filter(titleIs('Developer'));

let user = {name: 'Viola', age: 50, title: 'Actress', pets: ['Zak']};
isEmployed(user);   // true
isContractor(user); // false 

https://blog.csdn.net/wangpeng198688/article/details/51132294

箭头函数: 使用Lambda 表达式【()->{} 】定义的修复了this的指向的匿名函数
ps. 箭头函数在this定义的时候保存了当前作用域链,而不是在调用时根据调用位置决定,
箭头函数体里的this对象是定义时所在的对象,而不是调用时所在的对象。

function foo(){return (a)=>{console.log(this.a);}}
var obj1={a:1}
var obj2={a:2}
var bar=foo.call(obj1)//定义的位置
bar.call(obj2)// 调用的位置
// 1 

箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj
“Lambda 表达式”(lambda expression)是匿名函数的别称。
在ES6中,允许使用箭头=>定义匿名函数。
lamdba表达式的组成:参数列表,箭头,以及一个语句块或者是表达式. 如下
()->{}
()为参数列表,参数的类型可以省略

执行上下文定义了变量或函数有权访问的其他数据,决定了他们各自的行为。当javascript代码执行一段可执行代码时,会创建对应的执行上下文;
代码全部执行完后,该执行上下文也会被销毁,保存在其中的变量和函数定义也随之被销毁。执行上下文会管理代码执行过程中使用的内存。

闭包:实现函数声明过程中环境信息所属函数绑定在一起的数据结构。

上一篇下一篇

猜你喜欢

热点阅读