SOURCE

// 函数作为参数传递

function forEach(arr, fn) {
    for (let i = 0; i < arr.length; i++) {
        fn(arr[i])
    }
}

function filter(arr, fn) {
    let result = []
    for (let i = 0; i < arr.length; i++) {
        if (fn(arr[i])) {
            result.push(arr[i])
        }
    }
    return result
}

// let arr = [1, 3, 4, 5, 6, 26]

// let r = filter(arr, (item) => item % 2 === 0)
// console.log(r)

// forEach(arr, (item) => { console.log(item) })

// 高阶函数 - 函数作为返回值
function makeFn() {
    let msg = "Hello function"
    return function () {
        console.log(msg)
    }
}

// const fn = makeFn()
// fn()

// makeFn()()

// once
function once(fn) {
    let done = false
    return function () {
        if (!done) {
            done = true
            fn.apply(this, arguments)
        }
    }
}

function payOne(money) {
    console.log('支付了' + money)
}

let pay = once(payOne)
// console.log(pay)

// pay(5)
// pay(5)
// pay(5)
// pay(5)

/**
 * 使用高阶函数的意义
 * - 抽象可以帮我们屏蔽细节,只需要关注于我们的目标
 * - 高阶函数是用来抽象通用的问题
 */

// 常用高阶函数:map、every、some
const map = (array, fn) => {
    let result = []
    for (let value of array) {
        result.push(fn(value))
    }
    return result
}

const every = (array, fn) => {
    let result = true
    for (let value of array) {
        result = fn(value)
        if (!result) {
            break
        }
    }
    return result
}

const some = (array, fn) => {
    let result = false;
    for (let value of array) {
        result = fn(value)
        if (result) {
            break
        }
    }
    return result
}

// let arr = [12, 2, 3, 4, 5]
// let r = map(arr, v => v * v)
// let r = every(arr, v => v > 1)
// let r = some(arr, v => v > 19)
// console.log(r)

// 闭包(Closure):函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。
// 可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员
// 闭包的本质:函数在执行的时候会放到一个执行栈上当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为被
// 外部引用不能释放,因此内部函数依然可以访问外部函数的成员
console 命令行工具 X clear

                    
>
console