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

相關文章
相關標籤/搜索