函数可以作为参数传递给另一个函数。
函数可以作为另一个函数的返回值。
// 手写 forEach 方法
function forEach(array, callback) {
for (let i = 0; i < array.length; i++) {
let item = array[i]
callback(item, i)
}
return array
}
// 测试
const arr = [14, 26, 4, 8, 9, 10]
forEach(arr, (item, index) => {
console.log(item, index)
})
// 手写 filter 方法
function filter(array, callback) {
const result = []
for (let i = 0; i < array.length; i++) {
let item = array[i]
if (callback(item, i, array)) {
result.push(item)
}
}
return result
}
// 测试
const arr = [14, 26, 4, 8, 9, 10]
const newArr = filter(arr, item => {
return item >= 10
})
console.log(newArr) // output: [ 14, 26, 10 ]
// 闭包 showMessage 方法
function showMessage() {
const message = 'Hi, coder!'
return function () {
console.log(message)
return message
}
}
const messge = showMessage()
messge()
// 手写 once 函数
// 模拟支付场景
function once(callback) {
// 变量判断是否执行
let flag = false
return function () {
// 第一次执行才生效
if (!flag) {
flag = true
// 将返回函数的 arguments 用 apply方法转为数组
// arguments 本来是伪数组
callback.apply(this, arguments)
}
}
}
function pay(params) {
console.log(`支付了${params}元`)
}
const fn = once(pay)
fn(50) // output: 支付了50元 只会执行一次
fn(50)
fn(50)
fn(50)
fn(50)
fn(50)
抽象可以帮我们屏蔽细节,只需要关注我们的目标,即关注函数的结果
高阶函数是用来抽象通用的问题
// 面向过程的方式
let array = [1, 2, 3, 4]
for (let i = 0; i < array.length; i++) {
console.log(array[i])
}
// 高阶高阶函数
let array = [1, 2, 3, 4]
forEach(array, item => {
console.log(item)
})
let r = filter(array, item => {
return item % 2 === 0
})
function map(array, callback) {
const result = []
for (let i = 0; i < array.length; i++) {
const item = array[i]
result.push(callback(item, i, array))
}
return result
}
// 测试
const arr = [1, 2, 3, 4]
const newArr = map(arr, item => {
return item * item
})
console.log(newArr) // output: [ 1, 4, 9, 16 ]
// 手写数组 some 方法
function some(array, callback) {
let result = false
for (let i = 0; i < array.length; i++) {
let item = array[i]
result = callback(item, i, array)
if (result) {
break
}
}
return result
}
const arr = [1, 2, 3, 4, 5, 6, 7]
console.log(
some(arr, item => {
return item > 7 // output: false
})
)
console.log(
some(arr, item => {
return item > 6 // output: true
})
)
// 手写数组 every 方法
function every(array, callback) {
let result = false
for (let i = 0; i < array.length; i++) {
let item = array[i]
result = callback(item, i, array)
if (!result) {
break
}
}
return result
}
const arr = [1, 2, 3, 4, 5, 6, 7]
console.log(
every(arr, item => {
return item < 8 // output:true
})
)
console.log(
every(arr, item => {
return item < 7 // output: false
})
)
// 按指定下标递加
{
function reduce(array, callback, index) {
let result = array[index]
for (let i = index + 1; i < array.length; i++) {
let currItem = array[i]
result = callback(result, currItem)
}
return result
}
const arr = [1, 2, 3, 4, 5]
function sum(curr, next) {
console.log(curr, next)
return curr + next
}
console.log(reduce(arr, sum, 0)) // output: 15
console.log(reduce(arr, sum, 3)) // output: 9
}
// 从指定值开始递增
{
function reduce(array, callback, initValue) {
let result = initValue
for (let i = 0; i < array.length; i++) {
let currItem = array[i]
result = callback(result, currItem)
}
return result
}
const arr = [1, 2, 3, 4, 5]
function sum(curr, next) {
console.log(curr, next)
return curr + next
}
console.log(reduce(arr, sum, 0)) // output: 15
console.log(reduce(arr, sum, 3)) // output: 18
console.log(arr.reduce(sum, 3)) // output:18
}
方法sort()将在原数组上对数组元素进行排序,即排序时不创建新的数组副本。如果调用方法sort()时没有使用参数,将按字母顺序(更为精确地说,是按照字符编码的顺序)对数组中的元素进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如果有必要的话),以便进行比较。
如果想按照别的顺序进行排序,就必须提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数a和b,其返回值如下:
如果根据你的评判标准,a小于b,在排序后的数组中a应该出现在b之前,就返回一个小于0的值。
如果a等于b,就返回0。
如果a大于b,就返回一个大于0的值。
function sort(array, callback) {
if (!callback) {
for (let i = 0; i < array.length; i++) {}
}
}