1、深拷贝
/**
* 深拷贝
* @param {Object} obj 要拷贝的对象
* @param {Map} map 用于存储循环引用对象的地址
*/
function deepClone(obj = {}, map = new Map()) {
//不是对象类型,直接返回数据
if (typeof obj !== "object") return obj;
if (map.get(obj)) {
return map.get(obj);
}
// 初始化返回结果
let result = {};
//判断是数组,定义返回类型为数组,双重判断是否数数组类型,预防Array 的 prototype 被重写
if ( obj instanceof Array || Object.prototype.toString(obj) === "[object Array]" ) {
result = [];
}
// 防止循环引用
map.set(obj, result);
for (const key in obj) {
// 保证 key 不是原型属性
if (obj.hasOwnProperty(key)) {
// 递归调用
result[key] = deepClone(obj[key], map);
}
}
// 返回结果
return result;
}
2、数组去重
/**
* 数组去重 方法一 利用object的键唯一性
* @param {Array} arr 需要去重的数组
*/
function uniqueArr(arr){
let result = [];
const hashMap = {};
for(let i = 0; i < arr.length; i++){
const temp = arr[i]
if(!hashMap[temp]){
hashMap[temp] = true
result.push(temp)
}
}
return result;
}
//方法二 利用set 的值唯一性
Array.from(new Set(arr))
//方法三
[...new Set(arr)]
3、多维数组的展平
// 展平一级
function flat(arr){
var result = [];
for(var i = 0; i < arr.length; i++){
if(Array.isArray(arr[i])){
result = result.concat(flat(arr[i]))
}else{
result.push(arr[i]);
}
}
return result;
}
// 展平多级
function flattenByDeep(array,deep){
var result = [];
for(var i = 0 ; i < array.length; i++){
if(Array.isArray(array[i]) && deep > 1){
result = result.concat(flattenByDeep(array[i],deep -1))
}else{
result.push(array[i])
}
}
return result;
}
4、Compose 函数的实现 从右执行
compose函数
compose函数可以将需要嵌套执行的函数平铺,嵌套执行就是一个函数的返回值将作为另一个函数的参数。他的顺序是从右往左,可用使用reduceRight实现
//es5 实现方式
const compose = function(){
const args = [].slice.apply(arguments);
return function(x) {
return args.reduceRight((res, cb) => cb(res), x);
}
}
//es6 实现方式
const compose = (...args) => x => args.reduceRight((res, cb) => cb(res), x);
5、Pipe 函数的实现 从左执行
pipe函数
pipe函数跟compose函数的左右是一样的,也是将参数平铺,只不过他的顺序是从左往。我们来实现下,只需要将reduceRight改成reduce就行了:
//es5 实现
const pipe = function(){
const args = [].slice.apply(arguments);
return function(x) {
return args.reduce((res, cb) => cb(res), x);
}
}
//es6 实现
const pipe = (...args) => x => args.reduce((res, cb) => cb(res), x)
6、柯里化 函数实现 curry
什么是curried 函数
curried函数是个一次一个的去获取多个参数的函数。 再明白点,就是比如 给定一个带有3个参数的函数,curried版的函数将接受一个参数并返回一个接受下一个参数的函数,该函数返回一个接受第三个参数的函数。最后一个函数返回将函数应用于其所有参数的结果
实现思路
- 通过闭包的方式储存传入参数
- 通过函数的length属性获得参数个数
- 当参数个数不够时直接返回方法
- 存储的参数个数等于原函数参数个数时执行原函数
- 如果使用ES6参数默认值,length将不等于实际参数个数
- 参数由arguments获取,ES6直接使用rest参数实现
function curry(fn) {
const length = fn.length;
const curryFn = (args) => (arg) => {
const curryArgs = args.concat(arg);
if (curryArgs.length === length) {
return fn(...curryArgs);
}
return curryFn(curryArgs);
}
return curryFn([]);
}