javascript Array数组对象的扩展函数代码

  今天重点讲下 如何给Array对象扩展

  1、直接在Array.prototype 上扩展

  2、用自己方法对数组对象进行扩展

  直接在Array.prototype上扩展,不能直接对dom对象使用(如:document.getElementsByTagName('div')得到的nodeList);

  对有洁癖的同学而言 也破了原始生态环境的 : )

  先来看下 yui操作数组的一些方法,这里我对源码简单剥离并改动了下

  

复制代码 代码如下:

  (function(){

  var YArray;

  YArray = function(o,idx,arraylike){

  var t = (arraylike) ? 2 : YArray.test(o),

  l, a, start = idx || 0;

  if (t) {

  try {

  return Array.prototype.slice.call(o, start); //借助Array原生方法来把aguments转换为JS数组

  } catch(e) {

  a = [];

  l = o.length;

  for (; start<l; start++) {

  a.push(o[start]);

  }

  return a;

  }

  } else {

  return [o];

  }

  }

  YArray.test = function(o){

  var r = 0;

  if (o && (typeof o == 'object' ||typeof o == 'function')) {

  if (Object.prototype.toString.call(o) === "[object Array]") {

  r = 1;

  } else {

  try {

  if (('length' in o) && !o.tagName && !o.alert && !o.apply) {

  r = 2;

  }

  } catch(e) {}

  }

  }

  return r;

  }

  YArray.each = (Array.prototype.forEach) ? //先检测浏览器是否已支持,若有则调用原生

  function (a, f, o) {

  Array.prototype.forEach.call(a || [], f, o || Y);

  return YArray;

  } :

  function (a, f, o) {

  var l = (a && a.length) || 0, i;

  for (i = 0; i < l; i=i+1) {

  f.call(o || Y, a[i], i, a);

  }

  return YArray;

  };

  YArray.hash = function(k, v) {

  var o = {}, l = k.length, vl = v && v.length, i;

  for (i=0; i<l; i=i+1) {

  if (k[i]) {

  o[k[i]] = (vl && vl > i) ? v[i] : true;

  }

  }

  return o;

  };

  YArray.indexOf = (Array.prototype.indexOf) ?

  function(a, val) {

  return Array.prototype.indexOf.call(a, val);

  } :

  function(a, val) {

  for (var i=0; i<a.length; i=i+1) {

  if (a[i] === val) {

  return i;

  }

  }

  return -1; //寻找不到的情况

  };

  YArray.numericSort = function(a, b) {

  return (a - b); //从小到大排序, return (b - a); 从大到小

  };

  YArray.some = (Array.prototype.some) ?

  function (a, f, o) {

  return Array.prototype.some.call(a, f, o);

  } :

  function (a, f, o) {

  var l = a.length, i;

  for (i=0; i<l; i=i+1) {

  if (f.call(o, a[i], i, a)) {

  return true;

  }

  }

  return false;

  };

  })();

  借助Array原生方法来把aguments转换为JS数组的其他方法 (Dom对象不可以,只有遍历)

  

复制代码 代码如下:

  Array.apply(null,arguments);

  [].slice.call(arguments,0);

  [].splice.call(arguments,0,arguments.length);

  [].concat.apply([],arguments);

  ...

  YArray函数不仅可以操作数组对象也对nodeList对象进行了操作

  YArray(document.getElementsByTagName("div"));

  遍历dom对象 重新组装成一个数组 : )

  

复制代码 代码如下:

  a = [];

  l = o.length;

  for (; start<l; start++) {

  a.push(o[start]);

  }

  return a;

  YArray.each

  遍历数组,如有传入函数,每次遍历都执行callback

  

复制代码 代码如下:

  YArray.each([1,2,3],function(item){

  alert(item);// 执行了3次,1,2,3

  });

  YArray.hash

  数组 组装成 键值对 可以理解成一个json对象

  YArray.hash(["a","b"],[1,2]);

  YArray.indexOf

  返回(想要找寻值)一样的该值在数组的索引值

  YArray.indexOf([1,2],1)

  YArray.numericSort

  对数组进行排序,从小到大

  [3, 1, 2].sort(YArray.numericSort);

  YArray.some

  是否数组中的有元素通过了callBack的处理?如果有,则立马返回true,如果一个都没有,则返回false

  

复制代码 代码如下:

  YArray.some([3, 1, 2],function(el){

  return el < 4;

  })

  让我们看看 javascript 1.6 -1.8 对数组的扩展 ,并学习如何实现相同的功能

  every

  filter

  forEach

  indexOf

  lastIndexOf

  map

  some

  reduce

  reduceRight

  Array.prototype.every

  

复制代码 代码如下:

  if (!Array.prototype.every)

  {

  Array.prototype.every = function(fun /*, thisp*/)

  {

  var len = this.length >>> 0;

  if (typeof fun != "function")

  throw new TypeError();

  var thisp = arguments[1];

  for (var i = 0; i < len; i++)

  {

  if (i in this &&

  !fun.call(thisp, this[i], i, this))

  return false;

  }

  return true;

  };

  }

  是否数组中的每个元素都通过了callBack的处理?如果是,则返回true,如果有一个不是,则立马返回false

  这和我们刚才提到的YUI种的 some 函数 很雷同 :) 功能刚好相反

  Array.prototype.filter

  

复制代码 代码如下:

  Array.prototype.filter = function (block /*, thisp */) { //过滤器 ,添加方便,进行判断过滤

  var values = [];

  var thisp = arguments[1];

  for (var i = 0; i < this.length; i++)

  if (block.call(thisp, this[i]))

  values.push(this[i]);

  return values;

  };

  使用方法

  

复制代码 代码如下:

  var val= numbers.filter(function(t){

  return t < 5 ;

  })

  alert(val);

  forEach 和 indexOf 和 some 可以参考 上面yui的代码 ,不再重述

  lastIndexOf 和 indexOf 代码相似 只是从最后开始遍历

  下面讲下 ‘ map'

  

复制代码 代码如下:

  Array.prototype.map = function(fun /*, thisp*/) {

  var len = this.length >>> 0;

  if (typeof fun != "function")

  throw new TypeError();

  var res = new Array(len);

  var thisp = arguments[1];

  for (var i = 0; i < len; i++) {

  if (i in this)

  res[i] = fun.call(thisp, this[i], i, this);

  }

  return res;

  };

  遍历数组,执行函数,迭代数组,每个元素作为参数执行callBack方法,由callBack方法对每个元素进行处理,最后返回处理后的一个数组

  var numbers = [1, 4, 9];

  var roots = numbers.map(function(a){return a * 2});

  Array.prototype.reduce

  

复制代码 代码如下:

  Array.prototype.reduce = function(fun /*, initial*/) {

  var len = this.length >>> 0;

  if (typeof fun != "function")

  throw new TypeError();

  if (len == 0 && arguments.length == 1)

  throw new TypeError();

  var i = 0;

  if (arguments.length >= 2) {

  var rv = arguments[1];

  } else {

  do {

  if (i in this) {

  rv = this[i++];

  break;

  }

  if (++i >= len)

  throw new TypeError();

  } while (true);

  }

  for (; i < len; i++) {

  if (i in this)

  rv = fun.call(null, rv, this[i], i, this);

  }

  return rv;

  };

  让数组元素依次调用给定函数,最后返回一个值,换言之给定函数一定要用返回值

  Array.prototype.reduceRight

  见名故而思意,从右往左

  

复制代码 代码如下:

  Array.prototype.reduceRight = function(fun /*, initial*/) {

  var len = this.length >>> 0;

  if (typeof fun != "function")

  throw new TypeError();

  if (len == 0 && arguments.length == 1)

  throw new TypeError();

  var i = len - 1;

  if (arguments.length >= 2) {

  var rv = arguments[1];

  } else {

  do {

  if (i in this) {

  rv = this[i--];

  break;

  }

  if (--i < 0)

  throw new TypeError();

  } while (true);

  }

  for (; i >= 0; i--) {

  if (i in this)

  rv = fun.call(null, rv, this[i], i, this);

  }

  return rv;

  };

  除了这些,只用想用到的方法都能加到Array.prototype上

  比如常用的toString

  

复制代码 代码如下:

  Array.prototype.toString = function () {

  return this.join('');

  };

  还可以添加 toJson ,uniq ,compact,reverse等

  Array扩展对开发还是很有帮助滴 : )