JavaScript高级编程

1.组合函数

1.Es5

function compose() {
          var args = Array.prototype.slice.call(arguments);
          return function(x) {
            return args.reduceRight(function(res, cb) {
              return cb(res);
            }, x);
          };
        }
复制代码

2.Es6

const compose1 = (...args) => x => args.reduceRight((res, cb) => cb(res), x);
复制代码
测试:
        function toUpperCase(str) {
            return str.toUpperCase();
        }

        function split(str) {
            return str.split('')
        }

        function reverse(arr) {
            return arr.reverse()
        }

        function join(arr) {
            return arr.join('-')
        }

        function add(str) {
            return str + '!'
        }
        var f1 = compose1(add, join, reverse, split, toUpperCase);
        console.log(f1('time')) // E-M-I-T!
复制代码

2.柯里化

1.ES5

function sub_curry(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        return fn.apply(this, args.concat([].slice.call(arguments)));
    };
}

function curry(fn, length) {

    length = length || fn.length;

    var slice = Array.prototype.slice;

    return function() {
        if (arguments.length < length) {
            var combined = [fn].concat(slice.call(arguments));
            return curry(sub_curry.apply(this, combined), length - arguments.length);
        } else {
            return fn.apply(this, arguments);
        }
    };
}
复制代码

2. Es6

var curry = fn =>
            judge = (...args) =>
            args.length === fn.length ? fn(...args) : (arg) => judge(...args, arg)
            
测试:
    var fn = curry(function(a, b, c) {
        console.log([a, b, c]);
    });
    
    fn("a", "b", "c") // ["a", "b", "c"]
    fn("a", "b")("c") // ["a", "b", "c"]
    fn("a")("b")("c") // ["a", "b", "c"]
    fn("a")("b", "c") // ["a", "b", "c"]
复制代码

3.防抖

function debounce(func, wait) {
  var timeout;

  return function() {
    var context = this; //使this指向dom对象而非window
    var args = arguments;

    clearTimeout(timeout);
    timeout = setTimeout(function() {
      func.apply(context, args);
    }, wait);
  };
}
复制代码

4.节流

//方式一:使用时间戳
function throttle1(func, wait) {
  var lastTime = 0;
  return function() {
    var args = arguments;
    var nowTime = +new Date();
    if (nowTime - lastTime > wait) {
      func.apply(this, args);
      lastTime = nowTime;
    }
  };
}
//方式二:使用定时器
function throttle2(func, wait) {
  var timeout;
  var previous = 0;

  return function() {
    context = this;
    args = arguments;
    if (!timeout) {
      timeout = setTimeout(function() {
        timeout = null;
        func.apply(context, args);
      }, wait);
    }
  };
}
复制代码

5.浅层克隆

1. 数组克隆

[].concat() [].slice()java

2.对象克隆

...运算符 Object.assign(targetObj,obj1,obj2)数组

3.封装函数

var shallowClone = function(obj) {
  if (typeof obj !== "object") return;
  // 根据obj的类型判断是新建一个数组仍是对象
  var newObj = obj instanceof Array ? [] : {};
  // 遍历obj,而且判断是obj的属性才拷贝
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
};
复制代码

6.深层克隆

1. 简便写法

function deepClone1(obj) {
  return JSON.parse(JSON.stringify(obj));
}
复制代码

2.多重对象递归

var deepClone2 = function(obj) {
  if (typeof obj !== "object") return;
  var newObj = obj instanceof Array ? [] : {};
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      //判断对象属性值是否为对象,若为对象递归该函数
      newObj[key] =
        typeof obj[key] === "object" ? deepClone2(obj[key]) : obj[key];
    }
  }
  return newObj;
};
复制代码

7.类型判断

function type(target) {
  var template = {
    "[object Array]": "array",
    "[object Object]": "object",
    "[object Null]": "null",
    "[object Number]": "number-object",
    "[object Boolen]": "boolen-object",
    "[object String]": "string-object"
  };
  if (typeof target == "object") {
    var str = Object.prototype.toString.call(target);
    return template[str]; //字符串属性需用[]
  } else return typeof target;
}
复制代码

8.数组去重

1.原始方法 对象和 NaN 不去重

Array.prototype.unique = function() {
  var temp = {},
    arr = [],
    len = this.length;
  for (i = 0; i < len; i++) {
    if (!temp[this[i]]) {
      temp[this[i]] = "a";
      arr.push(this[i]);
    }
  }
  return arr;
};
复制代码

2.filter方法 对象和 NaN 不去重

function unique(array) {
  var res = array.filter(function(item, index, array) {
    return array.indexOf(item) === index; // 去除重复元素依靠的是indexOf老是返回第一个元素的位置,
    后续的重复元素位置与indexOf返回的位置不相等,所以被filter滤掉了。
  });
  return res;
}

复制代码

3.Es6 set 对象不去重 NaN去重

`var unique = arr => [...new Set(arr)];bash

4.所有去重

function unique(array) {
  var obj = {};
  return array.filter(function(item, index, array) {
    return obj.hasOwnProperty(typeof item + JSON.stringify(item))
      ? false
      : (obj[typeof item + JSON.stringify(item)] = true);
  });
}
复制代码

9.求数组最大值或最小值

1.for循环

var arr = [6, 4, 1, 8, 2, 11, 23];
var result = arr[0];
for (var i = 1; i < arr.length; i++) {
  result = Math.max(result, arr[i]);
}
复制代码

2.sort排序

var arr = [6, 4, 1, 8, 2, 11, 23];

arr.sort(function(a, b) {
  return a - b;
});
console.log(arr[arr.length - 1], arr[0]); //最大值,最小值
复制代码

3.appaly

var arr = [6, 4, 1, 8, 2, 11, 23];
console.log(Math.max.apply(Math, arr));
复制代码

4.ES6 ...

var arr = [6, 4, 1, 8, 2, 11, 23];
console.log(Math.max(...arr));
复制代码

10.数组乱序

var values = [1, 2, 3, 4, 5];
values.sort(function(){
    return Math.random() - 0.5;
});
console.log(values)
复制代码

11.数组扁平化

1.循环遍历+递归

function flatten(arr) {
  var result = [];
  for (var i = 0, len = arr.length; i < len; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]));
    } else {
      result.push(arr[i]);
    }
  }
  return result;
}
复制代码

2.reduce

function flatten(arr) {
  return arr.reduce(function(prev, next) {
    return prev.concat(Array.isArray(next) ? flatten(next) : next);
  }, []);
}
复制代码

3.只扁平一层

[].concat(...arr);app

相关文章
相关标签/搜索