首页 > 代码库 > JavaScript全面学习(中高)
JavaScript全面学习(中高)
1.当代码块被try { ... }
包裹的时候,就表示这部分代码执行过程中可能会发生错误,一旦发生错误,就不再继续执行后续代码,转而跳到catch
块。catch (e) { ... }
包裹的代码就是错误处理代码,变量e
表示捕获到的错误。
最后,无论有没有错误,finally
一定会被执行。
catch
和finally
可以不必都出现
throw
语句主动抛出一个错误,让执行流程直接跳转到catch
块。
当我们用catch捕获错误时,一定要编写错误处理语句,哪怕仅仅把错误打印console.log
出来,也不要什么也不干。
如果在一个函数内部发生了错误,它自身没有捕获,错误就会被抛到外层调用函数,如果外层函数也没有捕获,该错误会一直沿着函数调用链向上抛出,直到被JavaScript引擎捕获,代码终止执行。
2.
function printTime() { throw new Error(); } try { setTimeout(printTime, 1000); console.log(‘done‘); } catch (e) { alert(‘error‘); }
这段代码无法弹出error,原因就在于调用setTimeout()
函数时,传入的printTime
函数并未立刻执行!紧接着,JavaScript引擎会继续执行console.log(‘done‘);
语句,而此时并没有错误发生。直到1秒钟后,执行printTime
函数时才发生错误,但此时除了在printTime
函数内部捕获错误外,外层代码并无法捕获。(全部函数执行完毕,再处理1000ms后的函数)
所以,涉及到异步代码,无法在调用时捕获,原因就是在捕获的当时,回调函数并未执行。
类似的,当我们处理一个事件时,在绑定事件的代码处,无法捕获事件处理函数的错误。
3.underscore.js
实现map()
操作(可以作用于Object):
_.map([1, 2, 3], (x) => x * x); // [1, 4, 9] _.map({ a: 1, b: 2, c: 3 }, (v, k) => k + ‘=‘ + v); // [‘a=1‘, ‘b=2‘, ‘c=3‘]
4.every / some
‘use strict‘; // 所有元素都大于0? _.every([1, 4, 7, -3, -9], (x) => x > 0); // false // 至少一个元素大于0? _.some([1, 4, 7, -3, -9], (x) => x > 0); // true
5.max / min
‘use strict‘; var arr = [3, 5, 7, 9]; _.max(arr); // 9 _.min(arr); // 3 // 空集合会返回-Infinity和Infinity,所以要先判断集合不为空: _.max([]) -Infinity _.min([]) Infinity
如果集合是Object,max()
和min()
只作用于value,忽略掉key:
_.max({ a: 1, b: 2, c: 3 }); // 3
6.groupBy()
把集合的元素按照key归类,key由传入的函数返回:
‘use strict‘; var scores = [20, 81, 75, 40, 91, 59, 77, 66, 72, 88, 99]; var groups = _.groupBy(scores, function (x) { if (x < 60) { return ‘C‘; } else if (x < 80) { return ‘B‘; } else { return ‘A‘; } }); // 结果: // { // A: [81, 91, 88, 99], // B: [75, 77, 66, 72], // C: [20, 40, 59] // }
7.shuffle / sample
shuffle()
用洗牌算法随机打乱一个集合:
‘use strict‘; // 注意每次结果都不一样: _.shuffle([1, 2, 3, 4, 5, 6]); // [3, 5, 4, 6, 2, 1]
sample()
随机选择一个或多个元素:
‘use strict‘; // 注意每次结果都不一样: // 随机选1个: _.sample([1, 2, 3, 4, 5, 6]); // 2 // 随机选3个: _.sample([1, 2, 3, 4, 5, 6], 3); // [6, 1, 4]
8.flatten()
接收一个Array
,无论这个Array
里面嵌套了多少个Array
,flatten()
最后都把它们变成一个一维数组:
_.flatten([1, [2], [3, [[4], [5]]]]); // [1, 2, 3, 4, 5]
9.first / last
var arr = [2, 4, 6, 8]; _.first(arr); // 2 _.last(arr); // 8
10.zip / unzip
var names = [‘Adam‘, ‘Lisa‘, ‘Bart‘]; var scores = [85, 92, 59]; _.zip(names, scores); // [[‘Adam‘, 85], [‘Lisa‘, 92], [‘Bart‘, 59]]
var namesAndScores = [[‘Adam‘, 85], [‘Lisa‘, 92], [‘Bart‘, 59]]; _.unzip(namesAndScores); // [[‘Adam‘, ‘Lisa‘, ‘Bart‘], [85, 92, 59]]
11.object
var names = [‘Adam‘, ‘Lisa‘, ‘Bart‘]; var scores = [85, 92, 59]; _.object(names, scores); // {Adam: 85, Lisa: 92, Bart: 59}
12.range
// 从0开始小于10: _.range(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // 从1开始小于11: _.range(1, 11); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // 从0开始小于30,步长5: _.range(0, 30, 5); // [0, 5, 10, 15, 20, 25] // 从0开始大于-10,步长-1: _.range(0, -10, -1); // [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
13.bind. 如果你想用log()
取代console.log(),可以这样写:
var log = console.log; // 调用call并传入console对象作为this: log.call(console, ‘Hello, world!‘) // 输出Hello, world!
如果用bind,把console
对象直接绑定在log()
的this
指针上。可以这样写:
var log = _.bind(console.log, console); log(‘Hello, world!‘); // 输出Hello, world!
14.partial()
为一个函数创建偏函数
假设我们经常计算2y,每次都写Math.pow(2, y)
就比较麻烦,如果创建一个新的函数能直接这样写pow2N(y)
就好了,这个新函数pow2N(y)
就是根据Math.pow(x, y)
创建出来的偏函数,它固定住了原函数的第一个参数(始终为2):
var pow2N = _.partial(Math.pow, 2); pow2N(3); // 8 pow2N(5); // 32 pow2N(10); // 1024
如果我们不想固定第一个参数,想固定第二个参数,比如,希望创建一个偏函数cube(x)
,计算x3,可以用_
作占位符,固定住第二个参数:
var cube = _.partial(Math.pow, _, 3); cube(3); // 27 cube(5); // 125 cube(10); // 1000
15.memoize能把结果缓存下来,再次调用不需要计算:
var factorial = _.memoize(function(n) {
console.log(‘start calculate ‘ + n + ‘!...‘);
var s = 1, i = n;
while (i > 1) {
s = s * i;
i --;
}
console.log(n + ‘! = ‘ + s);
return s;
});
// 第一次调用:
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!...
// 10! = 3628800
// 第二次调用:
factorial(10); // 3628800
// 控制台没有输出 但是,当你计算factorial(9)
的时候,仍然会重新计算
令每一次都保存:
var factorial = _.memoize(function(n) { console.log(‘start calculate ‘ + n + ‘!...‘); if (n < 2) { return 1; } return n * factorial(n - 1); }); factorial(10); // 3628800 // 输出结果说明factorial(1)~factorial(10)都已经缓存了: // start calculate 10!... // start calculate 9!... // start calculate 8!... // start calculate 7!... // start calculate 6!... // start calculate 5!... // start calculate 4!... // start calculate 3!... // start calculate 2!... // start calculate 1!... factorial(9); // 362880 // console无输出
JavaScript全面学习(中高)