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


Posted in Javascript onMay 22, 2010

今天重点讲下 如何给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扩展对开发还是很有帮助滴 : )
Javascript 相关文章推荐
初学Javascript的一些总结
Nov 03 Javascript
设置下载不需要倒计时cookie(倒计时代码)
Nov 19 Javascript
js实现在同一窗口浏览图片
Sep 17 Javascript
JavaScript中实现依赖注入的思路分享
Jan 15 Javascript
js实现分享到随页面滚动而滑动效果的方法
Apr 10 Javascript
js图片轮播效果实现代码
Apr 18 Javascript
整理Javascript函数学习笔记
Dec 01 Javascript
理解JS事件循环
Jan 07 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
Oct 16 Javascript
vue的常用组件操作方法应用分析
Apr 13 Javascript
jquery实现的简单轮播图功能【适合新手】
Aug 17 jQuery
JS实现电商商品展示放大镜特效
Jan 07 Javascript
javascript 正则替换 replace(regExp, function)用法
May 22 #Javascript
JQuery 文本框使用小结
May 22 #Javascript
基于Asp.net与Javascript控制的日期控件
May 22 #Javascript
jQueryPad 实用的jQuery测试工具(支持IE,chrome,FF)
May 22 #Javascript
用jQuery打造TabPanel效果代码
May 22 #Javascript
Mootools 图片展示插件(lightbox,ImageMenu)收集集合
May 21 #Javascript
jquery 多级下拉菜单核心代码
May 21 #Javascript
You might like
PHP 中检查或过滤IP地址的实现代码
2011/11/27 PHP
php mysql 判断update之后是否更新了的方法
2012/01/10 PHP
PHP扩展CURL的用法详解
2014/06/20 PHP
PHP Ajax JavaScript Json获取天气信息实现代码
2016/08/17 PHP
JavaScript 无符号右移赋值操作
2009/04/17 Javascript
理解Javascript_09_Function与Object
2010/10/16 Javascript
实现局部遮罩与关闭原理及代码
2013/02/04 Javascript
Javascript闭包(Closure)详解
2015/05/05 Javascript
ajax在兼容模式下失效的快速解决方法
2016/03/22 Javascript
javascript实现方法调用与方法触发小结
2016/03/26 Javascript
解决vue keep-alive 数据更新的问题
2018/09/21 Javascript
Node.js使用supervisor进行开发中调试的方法
2019/03/26 Javascript
在vue中使用vuex,修改state的值示例
2019/11/08 Javascript
webpack 动态批量加载文件的实现方法
2020/03/19 Javascript
[01:06]DOTA2小知识课堂 Ep.01 TP出门不要忘记帮队友灌瓶哦
2019/12/05 DOTA
Python 搭建Web站点之Web服务器与Web框架
2016/11/06 Python
python先序遍历二叉树问题
2017/11/10 Python
python使用pycharm环境调用opencv库
2018/02/11 Python
numpy找出array中的最大值,最小值实例
2018/04/03 Python
Python 微信之获取好友昵称并制作wordcloud的实例
2019/02/21 Python
python3实现微型的web服务器
2019/09/03 Python
Python ATM功能实现代码实例
2020/03/19 Python
python Canny边缘检测算法的实现
2020/04/24 Python
SneakerStudio英国:最佳运动鞋商店
2019/05/22 全球购物
英国索普公园票务和酒店套餐:Thorpe Breaks
2019/09/14 全球购物
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
高中生自我评语大全
2014/01/19 职场文书
全神贯注教学反思
2014/02/03 职场文书
学生不讲诚信检讨书
2014/09/29 职场文书
离婚协议书的范本
2015/01/27 职场文书
小学元宵节活动总结
2015/02/06 职场文书
高三教师工作总结2015
2015/07/21 职场文书
详解Java线程池是如何重复利用空闲线程的
2021/06/26 Java/Android
mysql分表之后如何平滑上线详解
2021/11/01 MySQL
Nginx工作模式及代理配置的使用细节
2022/03/21 Servers
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android