09js高阶函数

高阶函数

高阶函数

class Person {
      constructor(name, age) {
        this.name = name
        this.age = age
      }
    }
    const personArr = [
      new Person("张三", 49),
      new Person("李四", 50),
      new Person("杰克", 17),
      new Person("汤姆", 5),
    ]
    function filter(arr, cb) {
      const arrNew = []
      for(let i=0; i<arr.length; i++) {
        if( cb(arr[i]) ) {
          arrNew.push(arr[i])
        }
      }
      return arrNew
    }
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = filter(personArr, a => a.name === "张三" )
result = filter(personArr, a => a.age === 17 )
result = filter(arr, a => a%2 === 0 )
console.log(result)

filtr这种函数我们称为高阶函数, 即 一个函数的返回值或者参数是一个函数

  • 将函数作为参数, 称为回调函数, 意味着可以对一个函数动态的传递代码
function someFn() { //1.定义一个 someFn 函数
  return "hello"
}
function outer(cb) { //2.定义 outer 函数, 并声明形参cb, 且接受实参--> someFn 函数
  //返回值作为参数
  return () => {
    console.log('记录日志--')
    const result = cb() //5.将 someFn 函数的返回值, 赋值给result
    return result //6.将 someFn 函数的返回值作为 outer 函数的返回值, 返回
  }
}
let result = outer(someFn) //3.传入实参 someFn函数
console.log(result()) // -->4.调用outer函数	

function test() { //1.定义一个 test 函数
  console.log('test--')
  return "test"
}
let r = outer(test) //3.传入实参 test 函数
console.log(r()) //4. 调用 outer

在不修改原函数的基础功能上, 使可以增加其功能
通过高阶函数来动态生成一个新的函数

闭包

闭包的简介

function fn() {
  let num = 0
  //闭包
  return () => {
    num ++
    console.log(num)
  }
}
let result = fn()
console.log(result())

闭包:

闭包就是能访问到, 外部函数作用域中变量的函数, 在我们需要隐藏一些不希望被别人访问到的内容时可以使用闭包

闭包的构成:

  1. 函数的嵌套
  2. 内部函数要引用外部函数中的变量
  3. 内部函数要作为返回值返回

闭包的原理

let a = '全局变量a'
function fn() {
  console.log(a)
}
function fn2() {
  let a = 'fn2中的a'
  // console.log(a)
  fn()
}
fn2() // 全局变量a

function fn3() {
  let a = 'fn3中的a'
  function fn4() {
    console.log(a)
  }
  fn4()
}
fn3() //fn3中的a

function fn5() {
  let a = 'fn5中的a'
  function fn6() {
    console.log(a)
  }
  //闭包
  return fn6
}
let result = fn5()
console.log(result()) //fn5中的a

函数作用域, 在函数创建的时候就已经被确定(词法作用域)
闭包就是利用词法作用域

闭包的一些注意事项

function outer() {
  let someVariable = "someValue"
  //闭包
  return function() {
    console.log(someVariable)
  }
}
function outer2() {
  let num = 0
  return () => {
    num ++
    console.log(num)
  }
}
let fn = outer2()
let fn2 = outer2()
//闭包被创建
fn()
fn2()
//释放指针, 闭包销毁
// fn = null
// fn2 = null

闭包的生命周期:

  1. 闭包在外部函数调用时产生, 外部函数每次调用都会产生一个全新的闭包
  2. 在内部函数丢失时销毁, (内部函数被垃圾回收了, 闭包才会消失)

闭包的注意事项:

  1. 闭包主要用来隐藏一些不希望被外部访问到的内容, 这意味着闭包需要占用一定的空间,
  2. 相比较类来说, 闭包比较浪费内存空间(类可以使用原型,而原型不会重复创建, 但是闭包不能)
    1. 需要执行次数少时,使用闭包(推荐使用闭包,因为类存在this指向的问题)
  3. 需要大量创建实例时,使用类

递归

//求任意一个数的阶乘
//方式一:	循环方式
function jieCheng(num) {
  let result = 1
  for(let i=2; i<=num; i++) {
    result *= i
  }
  return result
}
let result = jieCheng(3);
console.log(result);
//方式二:	递归方式 -- 尽量打断点分步执行, 理解递归函数的执行机制
function jieCheng2(num) {
  //基线条件 -- num等于1时结束函数, 返回1
  if(num === 1) {
    return 1
  }
  //递归条件
  return jieCheng2(num-1) * num
}
console.log(jieCheng2(5))

递归:

  • 调用自身的函数称为递归函数
  • 递归的作用和循环基本一致

核心思想:把一个大的问题拆分成一个一个的小问题进行解决

注意: 递归比循环更耗费性能, (递归每次调用函数都会创建函数作用域,占用内存空间)

递归练习

//求斐波那契数列(从1开始, 当前数等于前两个数之和)的第n个数
//递归
function fib(num) {
  if(num <= 0) {
    return -1;
  }
  //基线条件
  if(num < 3) {
    return 1
  }
  //递归条件
  return fib(num-1) + fib(num-2)
}
console.log(fib(6))
//循环
function Fibo(n) {
  if(n <= 0) {
    return -1;
  }
  if(n <= 2) {
    return 1;
  }
  let pre = 1; //第一次循环pre是f(1)也就是1
  let next = 1; //第一次循环next是f(2)也就是1
  let n_value = 0; // 保存f(n)的值
  for(let i = 3; i <= n; i++) {
    n_value = pre + next;  //每一次循环n_value就是前两个数的和
    pre = next;  // 然后把next赋值给pre
    next = n_value;  //把新的n_value的值赋值给next
  }
  return n_value;
}
console.log(Fibo(12))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值