MooTools源码分析

Mootools源码分析(四)

时间:2015-06-29 14:24来源:网络整理 作者:KKWL 点击:
//对数组的扩展实现 Array.implement({  //迭代方法,call的使用  forEach: function(fn, bind){   for (var i = 0, l = this.length; i l; i++) fn.call(bind, this[i], i, this);  } }); //将each作为forEach的别名 Array.alias('

//对数组的扩展实现
Array.implement({

 //迭代方法,call的使用
 forEach: function(fn, bind){
  for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
 }

});

//将each作为forEach的别名
Array.alias('forEach', 'each');

//转为数组的快捷方式,但是在IE下,对于XML对象使用XPath查询后的结果,$A方法无法达到预期的结果
function $A(iterable){
 if (iterable.item){ //对于collection,使用for遍历复制到数组
  var array = [];
  for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
  return array;
 }

 //对于arguments和array对象,使用本方法可以转为数组
 return Array.prototype.slice.call(iterable);
};

//通用迭代遍历方法
function $each(iterable, fn, bind){
 var type = $type(iterable);
 ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind);
};

/*
对Array的扩展实现
对于迭代遍历时,给fn传递的参数依次为:当前数组项,当前项的索引值,当前数组对象,比如:
7前逢单7后双,判断月份大小的算法
function myfilter(item, i, arr){
 var half = arr.length / 2 + 1;
 return half > i && item % 2 || half <= i && !(item % 2);
}
[1,2,3,4,5,6,7,8,9,10,11,12].filter(myfilter);
上面的代码将返回[1, 3, 5, 7, 8, 10, 12]
然而,很多时候我们只需要使用第一个参数,即当前项的值
*/
Array.implement({

 //对数组的每一项使用一个逻辑判断,仅当所有项通过逻辑判断时返回true
 every: function(fn, bind){
  for (var i = 0, l = this.length; i < l; i++){
   if (!fn.call(bind, this[i], i, this)) return false;
  }
  return true;
 },

 //对数组进行逻辑过滤,返回包含所有通过逻辑判断的项的数组
 filter: function(fn, bind){
  var results = [];
  for (var i = 0, l = this.length; i < l; i++){
   if (fn.call(bind, this[i], i, this)) results.push(this[i]);
  }
  return results;
 },

 //配合$defined和filter方法,清除数组中的空项/
 clean: function() {
  return this.filter($defined);
 },

 /*
 类似String对象的indexOf方法,返回数组在指定位置开始查找指定的匹配项,并返回其索引值,没有找到时返回-1
 from参数可以在0和数组长度-1之间取值,也可以为负值,当为负值时表示开始查找的位置从后往前的位数
 */
 indexOf: function(item, from){
  var len = this.length;
  for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
   if (this[i] === item) return i; //注意这里用的是绝对等于===比较
  }
  return -1;
 },

 //对数组中的每项进行处理,fn函数的返回值将代表原位置的项,最后返回一个经处理后的新数组
 map: function(fn, bind){
  var results = [];
  for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this);
  return results;
 },

 //与every方法相反,只需要数组中的有一项满足条件就返回true
 some: function(fn, bind){
  for (var i = 0, l = this.length; i < l; i++){
   if (fn.call(bind, this[i], i, this)) return true;
  }
  return false;
 },

 //将两个数组关联,组成键-值表示的对象,注意数组充当键还是值的决定因素--当前数组的每项作为值
 associate: function(keys){
  var ōbj = {}, length = Math.min(this.length, keys.length);
  for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
  return obj;
 },

 //将数组的每项使用参数对象的方法进行处理,当返回true时当前项被添加到键值对象中作为值,处理的方法名作为键
 link: function(object){
  var result = {};
  for (var i = 0, l = this.length; i < l; i++){
   for (var key in object){
    if (object[key](this[i])){
     result[key] = this[i]; //键和值的关系
     delete object[key]; //保证result中键不重复,数组中索引值越小优先级越高
     break;
    }
   }
  }
  return result;
 },

 //利用index方法判断数组中是否包含指定项
 contains: function(item, from){
  return this.indexOf(item, from) != -1;
 },

 //扩展数组,将指定数组加到当前数组后面
 extend: function(array){
  for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
  return this;
 },

 //获取数组的最后一项,只是一个快捷方式
 getLast: function(){
  return (this.length) ? this[this.length - 1] : null;
 },

 //随机获取数组的一项
 getRandom: function(){
  return (this.length) ? this[$random(0, this.length - 1)] : null;
 },

------分隔线----------------------------