文章出處

  先介紹一下js中的高階函數,所謂的高階函數就是,一個函數中的參數是一個函數或者返回的是一個函數,就稱為高階函數。

  js中已經提高了一下高階函數,使用起來非常棒,當然我們也可以自己實現,我介紹幾種ES5/ES6新增的數組函數。

  首先是forEach,forEach它接受兩個參數,第一個函數,第二個傳一個this引用對象(可以不傳),函數支持傳3個參數第一個表示遍歷的當前值,第二個為索引,第三個表示當前對象。

[1,2,4,5].forEach(function(item,index){
  console.log(item,index);
})


  模擬forEach的實現

Array.prototype.for = function(fn){
  for(var i=0;i<this.length;i++){
    fn(this[i],i);
  }
};
[2,3,4,5,6].for(function(item,index){
  console.log(item,index);
})

  map返回處理過后的一個新數組


var arr = [1,2,3,4,5];
var a = arr.map(function(item,index){
  if(index>0){
    return item*index;
  }
  return item;
})

console.log(a); //[1, 2, 6, 12, 20]
console.log(arr); //[1, 2, 3, 4, 5]

  模擬實現map


var arr = [1,2,3,4,5];
Array.prototype.m = function(fn){
  var arr = [];
  for(var i=0;i<this.length;i++){
    arr.push(fn(this[i],i,this));
  }
  return arr;
};
console.log(arr.m(function(item,index,thisValue){
  console.log(thisValue); //[1, 2, 3, 4, 5]
  if(item>3){
    return item;
  }
  return item-1;
})) //[0, 1, 2, 4, 5]

  

  some方法用于檢測數組中的元素是否滿足指定條件,如果有一個元素滿足條件,則表達式返回true , 剩余的元素不會再執行檢測,如果沒有滿足條件的元素,則返回false。

Array.prototype.so = function(fn){
  for(var i=0;i<this.length;i++){
    if(fn(this[i],i,this)){
      return true;
    };
  }
  return false;
};

var arr = [1,2,3,4,5,6];

console.log(arr.so(function(item){
  return item>7;
}))

  filter返回滿足條件的值,是一個新數組。

Array.prototype.f = function(fn){
  var arr = [];
  for(var i=0;i<this.length;i++){
    fn(this[i],i,this)&&arr.push(this[i]);
  }
  return arr;
};
var arr = [1,2,3,4,5,6];
console.log(arr.f(function(item){
  return item<2;
}))

  every檢測數組所有元素是否都符合指定條件,如果數組中檢測到有一個元素不滿足,則整個表達式返回 false ,且剩余的元素不會再進行檢測。


Array.prototype.ev = function(fn){
  for(var i=0;i<this.length;i++){
    if(!fn(this[i],i,this)){
      return false;
    };
  }
  return true;
};

var arr = [1,2,3];

console.log(arr.ev(function(item){
  return item>1;
}))

 

函數柯里化

  簡單來說就是某些情況下我們執行某個函數,并不需要它直接返回一些值給我們,而是再我們需要的時候它再給我們返回,這就是函數柯里化,以下是某位大牛寫的。

一個 currying 的函數首先會接受一些參數,接受了這些參數之后,該函數并不會立即求值,而是繼續返回另外一個函數,剛才傳入的參數在函數形成的閉包中被保存起來。待到函數被真正需要求值的時候,之前傳入的所有參數都會被一次性用于求值。

 

不完全柯里化版

 

var fn = (function(){
  var num = 0;
  return function(){
    if(arguments.length===0){
      return num;
    }else{
      for(var i=0;i<arguments.length;i+=1){
        num+=arguments[i];
      }
    }
  };
}())

fn(2);
fn(2,2,2);
fn(2);
console.log(fn()); //10

柯里化版

var currying = function(fn){
var arrNum = [];
  return function(){
    if(arguments.length===0){
      return fn.apply(this,arrNum);
    }else{
      [].push.apply(arrNum,arguments);
      return arguments.callee;
    }
  };
}

var count = (function(){
  var num = 0;
  return function(){
    for(var i=0;i<arguments.length;i+=1){
      num+=arguments[i];
    }
    return num;
  };
}());

var s = currying(count);
s(3);
s(3,3,3);


console.log(s());

 

函數反柯里化unCurrying
創建一個應用范圍更廣的函數。使本來只有特定對象才適用的方法,擴展到更多的對象。

簡單版

var obj = {
"length": 3,
"0": 1,
"1": 2,
"2": 3
};

// Array.prototype.push.call(obj,3);
// console.log(obj);

function push(){
  var a = [].shift.call(arguments);
  Array.prototype.push.apply(a,arguments);
};
push(obj,3);
push(obj,30);
push(obj,'js');
console.log(obj);


也可以這樣。

var obj = {
"length": 3,
"0": 1,
"1": 2,
"2": 3
};

// Array.prototype.push.call(obj,3);
// console.log(obj);

Function.prototype.uncurrying = function(){
  var _this = this; //Array.prototype.push
  return function(){
    //刪除第一個,并且返回 obj
    var obj = [].shift.call(arguments);
    //obj調用Array.prototype.push方法,傳遞arguments,注意此時arguments已經沒有包含obj這個參數了。
    return _this.apply(obj,arguments);
  };
};

var push = Array.prototype.push.uncurrying();

console.log(push(obj,'666'));
console.log(obj)
push(obj,'777');
console.log(obj)


文章列表


不含病毒。www.avast.com
文章標籤
全站熱搜
創作者介紹
創作者 AutoPoster 的頭像
AutoPoster

互聯網 - 大數據

AutoPoster 發表在 痞客邦 留言(0) 人氣(12)