Functions are first-class citizen
Functions are first-class citizen in JavaScript, as the same as other types(e.g. number, array, object). They can be used as arguments, as well as return value from other function.
Take a simple example, if we aim to print out all the elements in an array, most people probably will do it this way:
function printWithLoop(arr) { for (let i = 0, len = arr.length; i < len; i++) { console.log(arr[i]); } }
If you"re a bit familar with higher-order function, you may be inclined to use Array.prototype.forEach:
function printWithIterator(arr) { (arr || []).forEach(it => { console.log(it); }); }
We can then simplify the code further with:
function simplePrint(arr) { (arr || []).forEach(console.log); }
Have a second thought here, is the output from simplePrint exactly the same as printWithIterator? If not, can you explain what makes the difference?
Function overloadingFunction overloading gives the ability for functions to behave differently based on the number or type of the arugments. E.g. Array.from.
When given a single argument, it simplely creates a new Array instance from an array-like or iterable object
let set = new Set(["foo", "bar", "foo"]); console.log(Array.from(set)); //["foo", "bar"]
When given a second argument mapFn which is optioinal, it will apply mapFn to each element when creating the new array.
console.log(Array.from([1, 2, 3], x => x + x)); // [2, 4, 6]Curry
Curry, also called partial application. Currying a function basically means that a function will absord some arguments and return another function for later invocation. The returning function can have access to the already absorded arguments through closure.
Parameters vs ArugmentsFirst we need to understand two basic concepts in functions.
Parameters: the placeholders in function declarations. We can use function.length to get the number of parameters.
function A(a, b) {} // a and b are parameters console.log(A.length); //2
Arguments: the values passed to functions when functions are applied. We can use arguments to get the list of arguments.
function B(a, b) { console.log(arguments); } B(1,2,3); // 1,2,3
To conclude, parameters are what you expect while arguments are what you got.
Curry exampleAssume we have a function to compute the sum of three numbers.
function sum(x, y, z) { console.log(x + y + z); } sum(1,2,3); //6
If we want to achieve the following result:
sum(1,2,3); //6 sum(1)(2,3); //6 sum(1,2)(3); //6
Have a deep look, what we want to achieve is that when the function sum receives the arguments it expects (i.e. three numbers), it will compute their sum and return the value. Otherwise, it will keep returning another function (e.g. sum(1) and sum(1,2) both return another function) which can be invoked with more numbers. This is Curry!
function curry(fn) { //Let"s ignore the function context for simplicity return function f(...args) { /** * if the number of passed in arguments is more than what we expect * invoke the function and return the result */ if(args.length >= fn.length) { return fn.apply(this, args); } else { //return another function which can access to the passed arguments through closure return function(...arr) { return f.apply(this, args.concat(arr)); } } } } let sumWithCurry = curry(sum); sumWithCurry(1,2,3); //6 sumWithCurry(1)(2,3); //6 sumWithCurry(1,2)(3); //6Function.prototype.bind
Function.prototype.bind has two main functionalities:
binding the function context this
curry
function sayHi(greeting, ending) { console.log(`My name is ${this.name}, ${greeting}. ${ending}!`); } let fn = sayHi.bind({name: "mike"}, "Love you"); // greeting is absorded fn("Thanks!"); // My name is mike, Love you. Thanks!!
In development, we can use curry to write more elegant code:
function print(arr) { console.log(arr.join("|")); } let arr = [1,2,3]; setTimeout(function(){ print([1,2,3]); }, 1000); // 1|2|3
is equivalent to
function print(arr) { console.log(arr.join("|")); } let arr = [1,2,3]; setTimeout(print.bind(null, arr), 1000); // 1|2|3Reference
Effective JavaScript
NoticeIf you want to follow the latest news/articles for the series of reading notes, Please 「Watch」to Subscribe.
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/93424.html
摘要:前端日報精選請求終極解決方案微信小程序之小白教程系列微信小程序樣式常用命令使用教程如何在三年內(nèi)快速成長為一名技術(shù)專家淺談前后端分離與實踐之中間層服務(wù)二中文框架教程阮一峰的網(wǎng)絡(luò)日志的組合功能如何用選項連接組合文件外部定義的容器眾 2017-10-24 前端日報 精選 JS HTTP 請求終極解決方案[微信小程序之小白教程系列] 微信小程序 -- 樣式(WXSS)常用Git命令使用教程如何...
摘要:都有個規(guī)則范疇格式化規(guī)則例減輕了對這整個類別規(guī)則的需求以一致的方式從頭開始輸出整個程序,所以程序員不可能再犯錯誤了。代碼質(zhì)量規(guī)則例不針對與此項。在這方面還是有無可替代的功勞譯者建議配合使用來管理維護(hù)更好的代碼輸出。 以下內(nèi)容為個人參照Prettier官網(wǎng)部分文檔翻譯+理解,用以羅列部分you need to know,文檔內(nèi)容經(jīng)供參考,詳細(xì)內(nèi)容參考官網(wǎng) 安裝 (由于node.js的火熱...
摘要:題目解答每一次比較只有兩種情況,是的話,那么肯定不是是的話,那么肯定不是所以一直比較到最后會留下一個,然后我們再驗證這個是不是正解。 題目:Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The defini...
Problem Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her ...
閱讀 930·2021-11-23 09:51
閱讀 993·2021-11-18 10:02
閱讀 1909·2021-09-10 11:27
閱讀 3140·2021-09-10 10:51
閱讀 779·2019-08-29 15:13
閱讀 2064·2019-08-29 11:32
閱讀 2502·2019-08-29 11:25
閱讀 3045·2019-08-26 11:46