Effective Javascript 阅读笔记(5)-JavaScript 高阶函数
2018-01-10 14:55
435 查看
所谓高阶函数,将函数作为参数或返回值的函数。将函数作为参数,通常又叫做回调函数。下面我们通过几个例子来理解一下高阶函数的定义。
函数数组的sort方法
标准库需要传递一个具有compare的方法作为对象,这就是一个高阶函数。我们可以简化为匿名函数。
掌握了这个方法,我们就可以用高阶函数简化自己的代码。需要引入高阶函数抽象的信号出现重复或相似的代码,例:
我们可以看到虽然这三个函数的结果以及方法都不相同,但是我们不难发现,其中都用到了for循环以及累加的相似逻辑。所以我们可以提取相同的部分,简化函数
这样把高阶函数抽象出来
可以增加函数的可读性
更简洁,利于函数的维护
更高效,增强了函数的可扩展性
一个简单的惰性加载的案例,浏览器检测。比如返回顶部,我们需要区分火狐浏览器还是其他浏览器来决定scrollTop 的赋值。
但是会有一个不完美的地方,当我们在代码中需要多处使用调用此函数的时候,我们每次都需要重新获取navigator.userAgent,然后进行判断,会多做一些无用功。所以我们进行一下改造
这样,改造完成之后,第一次进入浏览器的时候,浏览器的当前属性就已经赋值到gotop这个参数中并存储,当我们再次需要使用的时候,仅调用gotop这个参数就可以了不需要二次判断,提高了代码的效率。
函数作为参数
函数数组的sort方法function compareNumber(x, y) { if (x < y) { return -1; } if (x > y) { return 1; } return 0; } [3, 1, 4, 1, 5, 9].sort(compareNumber); //[1, 1, 3, 4, 5, 9]
标准库需要传递一个具有compare的方法作为对象,这就是一个高阶函数。我们可以简化为匿名函数。
[3, 1, 4, 1, 5, 9].sort( function (x, y) { if (x < y) { return -1; } if (x > y) { return 1; } return 0; }); //[1, 1, 3, 4, 5, 9]
掌握了这个方法,我们就可以用高阶函数简化自己的代码。需要引入高阶函数抽象的信号出现重复或相似的代码,例:
//生成a-z英文字母构造的字符串 var aIndex = 'a'.charCodeAt(0);//97 var alphabet = ''; for(var i = 0; i < 26; i++) { alphabet += String.fromCharCode(aIndex + i); } alphabet//'abcdefghigklmnopqistuvwxyz' //生成0-9的数字字符串 var digits = ''; for(var i = 0; i < 10; i++) { digits += i; } digits//'0123456789' //生成随机字符串 var random = ''; for(var i = 0; i < 8; i++) { random += String.fromCharCode(Math.floor(Math.random()*26)+aIndex); } random//'bdwvfrtp'(different r d894 esult each time )
我们可以看到虽然这三个函数的结果以及方法都不相同,但是我们不难发现,其中都用到了for循环以及累加的相似逻辑。所以我们可以提取相同的部分,简化函数
//提出公用的部分 function buildString(n, callback) { var result = ''; for(var i = 0; i < n; i++) { result += callback (i); } return result; } //简化上面的三个例子 var alphabet = buildString(26, function(i) { return String.fromCharCode(aIndex + i); }) var digits = buildString(10, function(i) { return i; }) var random = buildString(8, function(i) { return String.fromCharCode(Math.floor(Math.random() * 26) + aIndex) })
这样把高阶函数抽象出来
可以增加函数的可读性
更简洁,利于函数的维护
更高效,增强了函数的可扩展性
函数作为返回值
一个简单的惰性加载的案例,浏览器检测。比如返回顶部,我们需要区分火狐浏览器还是其他浏览器来决定scrollTop 的赋值。// 一般的写法 var gotop = function(){ if(/firefox/i.test(navigator.userAgent)) { document.documentElement.scrollTop = 0; } else { document.body.scrollTop = 0; } }
但是会有一个不完美的地方,当我们在代码中需要多处使用调用此函数的时候,我们每次都需要重新获取navigator.userAgent,然后进行判断,会多做一些无用功。所以我们进行一下改造
var gotop = (function(){ var isFF = /firefox/i.test(navigator.userAgent); var docEl = document[ isFF ? 'documentElement' : 'body' ]; return function(){ docEl.scrollTop = 0; } })();
这样,改造完成之后,第一次进入浏览器的时候,浏览器的当前属性就已经赋值到gotop这个参数中并存储,当我们再次需要使用的时候,仅调用gotop这个参数就可以了不需要二次判断,提高了代码的效率。
相关文章推荐
- Effective Javascript 阅读笔记(4)-JavaScript 三种不同的使用模式
- Effective Javascript 阅读笔记(1)-理解Javascript 的浮点数
- Effective Javascript 阅读笔记(2)-了解分号插入的局限
- [Effective JavaScript 笔记]第19条:熟练掌握高阶函数
- Effective Javascript 阅读笔记(3)-闭包
- 【JavaScript 高级程序设计阅读笔记】JSON
- [Effective JavaScript 笔记] 第8条:尽量少用全局对象
- More Effective C++ 阅读笔记(八)--“抛出一个异常”与“传递一个参数”或“调用一个虚函数”间的差异
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
- JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
- Javascript_Dom编程 阅读笔记(1)
- 【阅读笔记】JavaScript 高级程序设计(一)
- [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同
- [Effective JavaScript 笔记]第62条:在异步序列中使用嵌套或命名的回调函数
- [Effective JavaScript 笔记]第64条:对异步循环使用递归
- More Effective C++ 阅读笔记(十)--效率问题
- What makes for Effective detection proposals?论文阅读笔记
- [Effective JavaScript 笔记] 第10条:避免使用with
- JavaScript.The.Good.Parts阅读笔记(一)假值与===运算符