Prototype Array对象 学习

复制代码 代码如下:

  Array.from = $A;

  (function() {

  //Array原型的引用

  var arrayProto = Array.prototype,

  slice = arrayProto.slice,

  //JS 1.6里面会有原生的forEach方法

  _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available

  function each(iterator) {

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

  iterator(this[i]);

  }

  //如果不是JS1.6,_each设置成对象的each方法

  //这里的_each方法是覆盖了Enuerable里面的_each方法

  if (!_each) _each = each;

  function clear() {

  this.length = 0;

  return this;

  }

  function first() {

  return this[0];

  }

  function last() {

  return this[this.length - 1];

  }

  //返回所有Array内不为null的数据

  function compact() {

  return this.select(function(value) {

  return value != null;

  });

  }

  //把多维数组压成一维数组

  function flatten() {

  return this.inject([], function(array, value) {

  if (Object.isArray(value))

  return array.concat(value.flatten()); //这里有递归调用

  array.push(value);

  return array;

  });

  }

  function without() {

  var values = slice.call(arguments, 0);

  return this.select(function(value) {

  return !values.include(value);

  });

  }

  function reverse(inline) {

  return (inline !== false ? this : this.toArray())._reverse();

  }

  //返回所有Array内不重复的元素,如果数组是有序的,传入true参数,执行起来会更快

  function uniq(sorted) {

  return this.inject([], function(array, value, index) {

  if (0 == index || (sorted ? array.last() != value : !array.include(value)))

  array.push(value);

  return array;

  });

  }

  //取两个数组的交集

  function intersect(array) {

  return this.uniq().findAll(function(item) {

  return array.detect(function(value) { return item === value });

  });

  }

  function clone() {

  return slice.call(this, 0);

  }

  function size() {

  return this.length;

  }

  function inspect() {

  return '[' + this.map(Object.inspect).join(', ') + ']';

  }

  function toJSON() {

  var results = [];

  this.each(function(object) {

  var value = Object.toJSON(object);

  if (!Object.isUndefined(value)) results.push(value);

  });

  return '[' + results.join(', ') + ']';

  }

  function indexOf(item, i) {

  i || (i = 0);

  var length = this.length;

  if (i < 0) i = length + i;

  for (; i < length; i++)

  if (this[i] === item) return i;

  return -1;

  }

  function lastIndexOf(item, i) {

  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;

  var n = this.slice(0, i).reverse().indexOf(item);

  return (n < 0) ? n : i - n - 1;

  }

  function concat() {

  var array = slice.call(this, 0), item;

  for (var i = 0, length = arguments.length; i < length; i++) {

  item = arguments[i];

  //这的第二条件是防止把调用方法的数组元素也一起concat起来

  if (Object.isArray(item) && !('callee' in item)) {

  for (var j = 0, arrayLength = item.length; j < arrayLength; j++)

  array.push(item[j]);

  } else {

  array.push(item);

  }

  }

  return array;

  }

  //mixin Enumerable里面的方法

  Object.extend(arrayProto, Enumerable);

  if (!arrayProto._reverse)

  arrayProto._reverse = arrayProto.reverse;

  Object.extend(arrayProto, {

  _each: _each,

  clear: clear,

  first: first,

  last: last,

  compact: compact,

  flatten: flatten,

  without: without,

  reverse: reverse,

  uniq: uniq,

  intersect: intersect,

  clone: clone,

  toArray: clone,

  size: size,

  inspect: inspect,

  toJSON: toJSON

  });

  //这个bug网上没搜到,谁知道说一下?

  var CONCAT_ARGUMENTS_BUGGY = (function() {

  return [].concat(arguments)[0][0] !== 1;

  })(1,2)

  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;

  //检查JS是否原生支持indexOf和lastIndexOf方法,不支持则设置成对象内的方法

  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;

  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;

  })();

  clear

  clone

  compact

  each

  first

  flatten

  from

  indexOf

  inspect

  last

  reduce

  reverse

  size

  toArray

  toJSON

  uniq

  without

  下面给出一些方法的例子,简单的方法就不给出例子了。

  flatten():

  

复制代码 代码如下:

  ['frank', ['bob', 'lisa'], ['jill', ['tom', 'sally']]].flatten()

  // -> ['frank', 'bob', 'lisa', 'jill', 'tom', 'sally']

  reduce():这个方法的意思就是,如果数字里面有一个数据,这直接返回这个数据,否则返回原来的数组

  uniq():

  

复制代码 代码如下:

  ['Sam', 'Justin', 'Andrew', 'Dan', 'Sam'].uniq();

  // -> ['Sam', 'Justin', 'Andrew', 'Dan']

  ['Prototype', 'prototype'].uniq();

  // -> ['Prototype', 'prototype'] because String comparison is case-sensitive

  without():

  

复制代码 代码如下:

  [3, 5, 6, 1, 20].without(3)

  // -> [5, 6, 1, 20]

  [3, 5, 6, 1, 20].without(20, 6)

  // -> [3, 5, 1]