javaScript高階級函數

首先咱們須要知道什麼是高級函數

  • 函數做爲參數傳遞
  • 函數做爲返回值輸出

知足以上一個條件就能夠稱之爲高階級函數
java

函數做爲參數傳遞

看一下例子
閉包

function iterator () {
     const obj = {
        message: '123'
        status: false
    }
    obj.status = true
    return obj
}
const obj2 = iterator()
console.log(obj2) // { message: '123', status: true }
複製代碼

沒毛病,but 問題來了,產品經理走過來和你提了一個需求,咱們要在iterator 外面作一些事情,這個事情作完以後再判斷obj.status是要等於true仍是false。emmmmmm
app

好既然產品經理都這麼說了。那咱們就開幹吧。dom

function iterator (cb) {
     const obj = {
        message: '123'
        status: false
    }
    cb(obj)
    return obj
}
const obj2 = iterator((obj) => {
    console.log(obj2) // { message: '123', status: false }
    if (true) {
        obj.status = true
    } else {
        obj.status = false
    }
})
console.log(obj2) // { message: '123', status: true }
複製代碼

👏👏👏👏 完成了一個產品經理的需求。函數當值傳遞,這是一個高級函數
其實咱們平時寫的dom事件就是這樣子方式,經過傳入一個回調函數。函數

$('#btn').on('click', function() {
    $('#massage').show();
});
複製代碼

傳入了一個函數,當click監聽到了信息,就會執行你傳入的函數。
讓咱們來個稍微高級點的。
ui

觀察者模式this

class observer {
    constructor() {
        // 用來保存全部的事件
        this.obj = {}
    }
    emit (str) {
        // 發佈一個事件
        const params = Array.prototype.slice.call(arguments, 1)
        this.obj[str] = (cb) => {
            cb(...params)
        }
    }
    on (str, fn) {
        // 執行一個事件
        this.obj[str](fn)
    }
}

const ob = new observer()
ob.emit('click', 1234, 'abcd')
ob.on('click', (a,b) => { 
    console.log(a,b) // 1234, 'abcd'
})
複製代碼

沒毛病,雖然這個代碼缺少嚴謹,but 咱們只是爲了展現一下搞基函數的方式之一函數當參數傳遞。
spa

函數做爲返回值輸出

function func () {
        let a = 1
        return function () {
            return a++
        }
    }
    let bb = func()
    cosnole.log(bb())
    cosnole.log(bb())
    cosnole.log(bb())
    cosnole.log(bb())
複製代碼

相信你們對這個會打印啥都不陌生吧。prototype

//1 2 3 4
複製代碼

每一個函數都是一個閉包,js訪問一個變量是,會從自身做用域開始查找再慢慢向上查找,找到的第一個就取值。func這個函數 return 的這個function 沒有a這個變量,因此就報錯?no 可是它父親有啊。它會向上找到後執行操做。最後外面js又發現全局變量bb引用了 這個function。因此js的自動垃圾回收機制放了這個a變量一馬,沒有回收它.
code

so 咱們再來個稍微高級點的。

節流

function debounce(fn, time) {
  // 記錄當前執行函數狀態
    let timer = null;
    let context = this;
    let args = arguments;
     return function() {
        if (timer) {
            // 任你滑,多執行一次算我輸
            return false
        }
        timer = setTimeout(function() {
          clearTimeout(timer);
          timer = null
          fn.apply(context, args);
        }, time || 500);
      }
}
function foo() {
  console.log('你過來啊');
}

// 過 2 秒觸發一次
window.addEventListener('scroll', debounce(foo, 2000));
複製代碼

這是一個簡單的節流函數,做用就是節流。臥槽這麼粗暴的嗎? 是的,我們是一篇講解搞基函數的文章,說什麼節流。要什麼手錶.
經過返回一個函數,咱們實現了,一個簡單的節流函數。這是有同窗問,爲啥那麼複雜,咱們直接把timer變成一個全局變量不行嗎?能夠的。爲啥不這樣作你本身去想吧。知道了答案請留言。謝謝。

咱們的高級函數有不少玩法,好比柯理化和反柯理化。學無止境啊。

相關文章
相關標籤/搜索