【前端100問】Q84:請實(shí)現(xiàn)一個 add 函數(shù),滿足以下功能。

寫在前面

此系列來源于開源項(xiàng)目:前端 100 問:能搞懂 80%的請把簡歷給我
為了備戰(zhàn) 2021 春招
每天一題,督促自己
從多方面多角度總結(jié)答案,豐富知識
請實(shí)現(xiàn)一個 add 函數(shù),滿足以下功能。
簡書整合地址:前端 100 問

正文回答

題目
add(1);             // 1
add(1)(2);      // 3
add(1)(2)(3);// 6
add(1)(2, 3); // 6
add(1, 2)(3); // 6
add(1, 2, 3); // 6
回答
function add() {
  let args = [].slice.call(arguments);
  let fn = function () {
    let fn_args = [].slice.call(arguments);
    return add.apply(null, args.concat(fn_args));
  };
  fn.toString = function () {
    return args.reduce((a, b) => a + b);
  };
  return fn;
}
擴(kuò)展

原文:【進(jìn)階 6-1 期】JavaScript 高階函數(shù)淺析

高階函數(shù)

高階函數(shù)英文叫 Higher-order function,它的定義很簡單,就是至少滿足下列一個條件的函數(shù):

  • 接受一個或多個函數(shù)作為輸入
  • 輸出一個函數(shù)

也就是說高階函數(shù)是對其他函數(shù)進(jìn)行操作的函數(shù),可以將它們作為參數(shù)傳遞,或者是返回它們。 簡單來說,高階函數(shù)是一個接收函數(shù)作為參數(shù)傳遞或者將函數(shù)作為返回值輸出的函數(shù)。

函數(shù)作為參數(shù)傳遞

JavaScript 語言中內(nèi)置了一些高階函數(shù),比如 Array.prototype.map,Array.prototype.filterArray.prototype.reduce,它們接受一個函數(shù)作為參數(shù),并應(yīng)用這個函數(shù)到列表的每一個元素。我們來看看使用它們與不使用高階函數(shù)的方案對比。

Array.prototype.map

map() 方法創(chuàng)建一個新數(shù)組,其結(jié)果是該數(shù)組中的每個元素都調(diào)用一個提供的函數(shù)后返回的結(jié)果,原始數(shù)組不會改變。傳遞給 map 的回調(diào)函數(shù)(callback)接受三個參數(shù),分別是 currentValue、index(可選)、array(可選),除了 callback 之外還可以接受 this 值(可選),用于執(zhí)行 callback 函數(shù)時使用的 this 值。

來個簡單的例子方便理解,現(xiàn)在有一個數(shù)組 [1, 2, 3, 4],我們想要生成一個新數(shù)組,其每個元素皆是之前數(shù)組的兩倍,那么我們有下面兩種使用高階和不使用高階函數(shù)的方式來實(shí)現(xiàn)。

// 不使用高階函數(shù)
// 木易楊
const arr1 = [1, 2, 3, 4];
const arr2 = [];
for (let i = 0; i < arr1.length; i++) {
  arr2.push(arr1[i] * 2);
}

console.log(arr2);
// [2, 4, 6, 8]
console.log(arr1);
// [1, 2, 3, 4]

// 使用高階函數(shù)
// 木易楊
const arr1 = [1, 2, 3, 4];
const arr2 = arr1.map((item) => item * 2);

console.log(arr2);
// [2, 4, 6, 8]
console.log(arr1);
// [1, 2, 3, 4]

Array.prototype.filter

Array.prototype.reduce

函數(shù)作為返回值輸出

isType 函數(shù)

我們知道在判斷類型的時候可以通過 Object.prototype.toString.call 來獲取對應(yīng)對象返回的字符串,比如:

let isString = (obj) =>
  Object.prototype.toString.call(obj) === "[object String]";
let isArray = (obj) => Object.prototype.toString.call(obj) === "[object Array]";
let isNumber = (obj) =>
  Object.prototype.toString.call(obj) === "[object Number]";

可以發(fā)現(xiàn)上面三行代碼有很多重復(fù)代碼,只需要把具體的類型抽離出來就可以封裝成一個判斷類型的方法了,代碼如下。

let isType = (type) => (obj) => {
  return Object.prototype.toString.call(obj) === "[object " + type + "]";
};

isType("String")("123"); // true
isType("Array")([1, 2, 3]); // true
isType("Number")(123); // true

這里就是一個高階函數(shù),因?yàn)?isType 函數(shù)將 obj => { ... } 這一函數(shù)作為返回值輸出。

回到題目本身

我們知道打印函數(shù)時會自動調(diào)用 toString()方法,函數(shù) add(a) 返回一個閉包 sum(b),函數(shù) sum() 中累加計算 a = a + b,只需要重寫 sum.toString()方法返回變量 a 就可以了。

function add(a) {
    function sum(b) { // 使用閉包
        a = a + b; // 累加
        return sum;
    }
    sum.toString = function() { // 重寫toString()方法
        return a;
    }
    return sum; // 返回一個函數(shù)
}

add(1); // 1
add(1)(2);  // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
另外一道題目

將數(shù)組扁平化并去除其中重復(fù)數(shù)據(jù),最終得到一個升序且不重復(fù)的數(shù)組

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容