D - F 系列
1、防抖函数,限制高频触发
const debounce = (fn, ms = 0) => {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), ms);
};
};
- 可以运用在监听屏幕缩放,或者input 搜索时,做一些性能优化
2、转换首字母(或其他)大小写
const decapitalize = ([first, ...rest], upperRest = false) =>
first.toLowerCase() +
(upperRest ? rest.join('').toUpperCase() : rest.join(''));
decapitalize('FooBar'); // 'fooBar'
decapitalize('FooBar', true); // 'fOOBAR'
- [first, ...rest] 通过这种解构的方式将字符分割成数组,同时获取到首字母
3、深克隆
const deepClone = obj => {
if (obj === null) return null;
let clone = Object.assign({}, obj);
Object.keys(clone).forEach(
key =>
(clone[key] =
typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
);
// 如果是数组仍然会转成 key - value 形式
if (Array.isArray(obj)) {
// 添加 length 属性,便于 Array.from 进行转换(类数组或者可迭代对象)
clone.length = obj.length;
return Array.from(clone);
}
return clone;
};
4、数组打平
const deepFlatten = arr =>
[].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)))
// 数组打平 至指定深度
const flatten = (arr, depth = 1) =>
arr.reduce(
(a, v) =>
a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v),
[]
);
flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
- 利用 map 将多维数组中的值返回成新数组,最后再展开与 [] 连接
- 可以看到,在解决一些深层次嵌套问题时(深度冻结一个对象),大多会用到递归思想,以后类似问题可以往这方面思考
5、两个数组的交集(Set的使用)
const difference = (a, b) => {
const s = new Set(b);
return a.filter(x => !s.has(x));
}
difference([1, 2, 3, 3], [1, 2, 4]); // [3, 3]
- 补充几个关于 set 的小知识
- Set 对象允许你存储任何类型的唯一值(只会出现一次),无论是原始值或者是对象引用
- 同时 set 的原型上提供了几个方法,size()(值的个数),add()(尾部添加),clear()(清除set对象中的所有元素),has()(返回布尔值)...
与数组相关
- 除了使用 Array.from() 转换外,还可以使用 ... 展开操作符
- 去重相关
本例中主要使用 has() 方法来判断两数组中的交集
6、实现一个求阶乘的函数
const factorial = n =>
n < 0
? (() => {
throw new TypeError('Negative numbers are not allowed!');
})()
: n <= 1
? 1
: n * factorial(n - 1);
factorial(6); // 720
7、生成一个指定长度数组,包含斐波那契数列
const fibonacci = n =>
Array.from({ length: n }).reduce(
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
[]
);
fibonacci(6); // [0, 1, 1, 2, 3, 5]
- 通过 Array.from() 产生一个指定长度数组
- reduce() ,给定初始值为 [],再使用 concat() 进行连接 acc,同时就做累加了
- reduce()的好处就是 参数 acc 是上一次调用回调时返回的累积值
8、实现一个从右侧开始的数组遍历
const forEachRight = (arr, callback) =>
arr
.slice()
.reverse()
.forEach(callback);
forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
- 有点意思,从右侧开始遍历,其实就是先拷贝一个副本,然后颠倒,再遍历
9、全屏模式下打开或关闭一个元素
const fullscreen = (mode = true, el = 'body') =>
mode
? document.querySelector(el).requestFullscreen()
: document.exitFullscreen();
fullscreen(); // Opens `body` in fullscreen mode
fullscreen(false); // Exits fullscreen mode
- requestFullscreen() 这个倒是是没见过
10、节流函数
const throttle = (fn, wait) => {
let inThrottle, lastFn, lastTime;
return function() {
const context = this,
args = arguments;
if (!inThrottle) {
fn.apply(context, args);
lastTime = Date.now();
inThrottle = true;
} else {
clearTimeout(lastFn);
lastFn = setTimeout(function() {
if (Date.now() - lastTime >= wait) {
fn.apply(context, args);
lastTime = Date.now();
}
}, Math.max(wait - (Date.now() - lastTime), 0));
}
};
};
window.addEventListener(
'resize',
throttle(function(evt) {
console.log(window.innerWidth);
console.log(window.innerHeight);
}, 250)
); // Will log the window dimensions at most every 250ms