1. 解析url获取键(name)值对

harmony
1
2
3
4
5
const getURLParameters = url =>
url.match(/([^?=&]+)(=([^&]*))/g).reduce(
(a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}
);
// getURLParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'}

2. 取扩展名

harmony
1
2
3
4
5
// 方法一
return filename.split('.').pop();

// 方法二
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;

3. 更好的监听移出事件写法

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function handleEvent (eventName, {onElement, withCallback, useCapture = false} = {}, thisArg) {
const element = onElement || document.documentElement

function handler (event) {
if (typeof withCallback === 'function') {
withCallback.call(thisArg, event)
}
}

handler.destroy = function () {
return element.removeEventListener(eventName, handler, useCapture)
}

element.addEventListener(eventName, handler, useCapture)
return handler
}

// 你需要的时候
const handleClick = handleEvent('click', {
onElement: element,
withCallback: (event) => {
console.log('Tada!')
}
})

// 你想删除它的时候
handleClick.destroy()

4. 获取unix时间戳

harmony
1
2
3
4
5
const dateTime = Date.now();
const dateTime = new Date().getTime();
const dateTime = new Date('2012-06-08').getTime();
const dateTime = +new Date();
const dateTime = +new Date('2012-06-08');

5. break 或 continue

for循环支持这两个方法
其他扩展循环,例如forEach和some、every
都不具备这两个方法,但是可以通过return true/false来实现同样的原理

6. reduce 应用

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 普通用法 (累加,关联)
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
},0);

// 进阶用法(结合)
var reducers = {
totalInDollar: function(state, item) {
state.dollars += item.price;
return state;
},
totalInEuros : function(state, item) {
state.euros += item.price * 0.897424392;
return state;
},
totalInPounds : function(state, item) {
state.pounds += item.price * 0.692688671;
return state;
},
totalInYen : function(state, item) {
state.yens += item.price * 113.852;
return state;
}
// more...
};
var combineTotalPriceReducers = function(reducers) {
return function(state, item) {
return Object.keys(reducers).reduce(
function(nextState, key) {
reducers[key](state, item);
return state;
},
{}
);
}
};

7. 计算数组中的最大值/最小值

harmony
1
2
3
var numbers = [1, 2, 3, 4];
Math.max(...numbers) // 4
Math.min(...numbers) // 1

8. 多维数组扁平化

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, strict, output) {
output = output || [];
var idx = output.length;
for (var i = 0, length = getLength(input); i < length; i++) {
var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
// Flatten current level of array or arguments object.
if (shallow) {
var j = 0, len = value.length;
while (j < len) output[idx++] = value[j++];
} else {
flatten(value, shallow, strict, output);
idx = output.length;
}
} else if (!strict) {
output[idx++] = value;
}
}
return output;
};

// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, false);
};

9. 数组去重

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var deduped = [ 1, 1, 'a', 'a' ].filter( (el, i, arr) => arr.indexOf(el) === i);

console.log(deduped); // [ 1, 'a' ]

// 数组内含有对象的时候
function dedup(arr) {
var hashTable = {};

return arr.filter(function (el) {
var key = JSON.stringify(el);
var match = Boolean(hashTable[key]);

return (match ? false : hashTable[key] = true);
});
}

var deduped = dedup([
{ a: 1 },
{ a: 1 },
[ 1, 2 ],
[ 1, 2 ]
]);

console.log(deduped); // [ {a: 1}, [1, 2] ]

使用的JSON.stringify,String类型的key 将会被存储为一个字符串值,这样hashTable的key就唯一了。
可以区分[1, '1']

10. ++ –操作

harmony
1
2
3
4
5
6
7
var a = 2;
var b = a++; // 因为a++先返回a的值 之后才+1 所以先返回的是2 然后再+1
// 现在 a == 3 b == 2

var a = 2;
var b = ++a;
// 现在a和b都是3

11. 仅用一行生成[0, 1, …, N-1]数列

harmony
1
Array.from(new Array(N),(val,index)=>index+1);

12. 使对象属性有顺序

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 用Map
var myObject = new Map();
myObject.set('z', 1);
myObject.set('@', 2);
myObject.set('b', 3);
for (var [key, value] of myObject) {
console.log(key, value);
...
// z 1
// @ 2
// b 3

// 支持老浏览器
// 使用分开的数组
var objectKeys = [z, @, b, 1, 5];
for (item in objectKeys) {
myObject[item]
...

// 构建一个单属性对象(single-property objects)的数组
var myData = [{z: 1}, {'@': 2}, {b: 3}, {1: 4}, {5: 5}];

13. arguments作为参数

提取arguments方法

harmony
1
2
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

传递arguments给任何参数,将导致Chrome和Node中使用的V8引擎跳过对其的优化,这也将使性能相当慢。
优化方法:

harmony
1
2
3
4
var args = new Array(arguments.length);
for(var i = 0; i < args.length; ++i) {
args[i] = arguments[i];
}

14. 阶乘运算

使用递归。如果n小于或等于1, 则返回1。否则, 返回n的乘积和n - 1的阶乘。如果n为负数, 则引发异常。

harmony
1
2
3
4
const factorial = n =>
n < 0 ? (() => { throw new TypeError('Negative numbers are not allowed!') })()
: n <= 1 ? 1 : n * factorial(n - 1);
// factorial(6) -> 720

15. 斐波纳契数列

在数学上,斐波纳契数列以如下被以递归的方法定义:

1
2
F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*)
// 结果: 0,1,1,2,3,5,8,13,21,34,55,89,144...

16. 数组去重

harmony
1
2
3
4
5
6
7
8
ES6方法:
const distinctValuesOfArray = arr => [...new Set(arr)];
// distinctValuesOfArray([1,2,2,3,4,4,5]) -> [1,2,3,4,5]

// 兼容方法 加了字母排序
const filteredAndSortedKeywords = keywords
.filter((keyword, index) => keywords.lastIndexOf(keyword) === index)
.sort((a, b) => a < b ? -1 : 1);

17. 删除数组

harmony
1
2
var list = [1, 2, 3, 4];
list = []

将一个新的数组的引用赋值给变量,其他引用并不受影响。
这意味着以前数组的内容被引用的话将依旧存在于内存中,这将导致内存泄漏。

harmony
1
list.length = 0

删除数组里的所有内容,也将影响到其他引用。
如果你复制了一个数组(A 和 Copy-A),如果你用list.length = 0清空了它的内容,复制的数组也会清空它的内容。

harmony
1
2
3
var ary = [1,2,3,4]; 
ary.splice(0,ary.length);//清空数组
console.log(ary); // 输出 [],空数组,即被清空了

删除单个元素

harmony
1
2
3
4
5
//  方法一:delete方法
delete arr[1]

// 方法二:数组对象splice方法
arr.splice(1,1);

18. 随机数组值的顺序

harmony
1
2
const shuffle = arr => arr.sort(() => Math.random() - 0.5);
// shuffle([1,2,3]) -> [2,3,1]

当1和2比较的时候 执行了一次Math.random() - 0.5,
当比较2和3时候,还有1和3的时候都调用了这个,所以每次顺序都是不定的,
Math.random() - 0.5执行次数根据引擎排序机制而定

19. 什么是闭包

什么是闭包? 闭包是指函数有自由独立的变量。换句话说,定义在闭包中的函数可以“记忆”它创建时候的环境。
参考MDN的文档

20. 判断是否有某个属性

harmony
1
2
3
4
5
6
// 方法一:
if (myObject.name) { ... }
// 方法二:
myObject.hasOwnProperty('name');
// 方法三:可查找原型链
'name' in myObject;

21. 参数兼容字符串/数组

harmony
1
2
3
4
5
6
function printUpperCase(words) {
var elements = [].concat(words || []);
for (var i = 0; i < elements.length; i++) {
console.log(elements[i].toUpperCase());
}
}

22. switch 改造

harmony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
switch(color) {
case 'black':
printBlackBackground();
break;
case 'red':
printRedBackground();
break;
case 'blue':
printBlueBackground();
break;
case 'green':
printGreenBackground();
break;
default:
printYellowBackground();
}
// 改造后:
var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
'yellow': printYellowBackground
};


if (color in colorObj) {
colorObj[color]();
}

23. 更快的向数组内添加项

harmony
1
2
3
arr[arr.length] = 6; // 平均 5 632 856 ops/sec
arr.push(6); // 慢35.64%
arr2 = arr.concat([6]); // 慢62.67%
← Prev Next →