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 相关文章推荐
jQuery代码优化 事件委托篇
Nov 01 Javascript
js判断背景图片是否加载成功使用img的width实现
May 29 Javascript
如何让页面加载完成后执行js
Jun 26 Javascript
jQuery 快速结束当前正在执行的动画
Nov 20 Javascript
jQuery实现向下滑出的平滑下拉菜单效果
Aug 21 Javascript
jQuery AJAX timeout 超时问题详解
Jun 21 Javascript
js css3实现图片拖拽效果
Mar 04 Javascript
详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现
Mar 11 Javascript
vue实现简单表格组件实例详解
Apr 16 Javascript
ES6对象操作实例详解
May 23 Javascript
基于postman获取动态数据过程详解
Sep 08 Javascript
jQuery实现日历效果
Sep 11 jQuery
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
ip签名探针
2006/10/09 PHP
php 截取字符串并以零补齐str_pad() 函数
2011/05/07 PHP
JavaScript 中的事件教程
2007/04/05 Javascript
强大的jquery插件jqeuryUI做网页对话框效果!简单
2011/04/14 Javascript
JavaScript 基础篇之运算符、语句(二)
2012/04/07 Javascript
JavaScript字符串String和Array操作的有趣方法
2012/12/18 Javascript
JavaScript获取按钮所在form表单id的方法
2015/04/02 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
javascript中sort排序实例详解
2016/07/24 Javascript
vue.js初学入门教程(2)
2016/11/07 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
2016/12/08 Javascript
vue使用Axios做ajax请求详解
2017/06/07 Javascript
vue删除html内容的标签样式实例
2018/09/13 Javascript
Vue将props值实时传递 并可修改的操作
2020/08/09 Javascript
[38:42]完美世界DOTA2联赛循环赛 Matador vs Forest BO2第二场 11.05
2020/11/05 DOTA
Python3下错误AttributeError: ‘dict’ object has no attribute’iteritems‘的分析与解决
2017/07/06 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
基于python的ini配置文件操作工具类
2019/04/24 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
Python虚拟环境的原理及使用详解
2019/07/02 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
HTML5声音录制/播放功能的实现代码
2018/05/03 HTML / CSS
俄罗斯运动、健康和美容产品在线商店:Lactomin.ru
2020/07/23 全球购物
C语言笔试题
2014/09/04 面试题
应届毕业生的自我鉴定
2013/11/13 职场文书
大学生村官工作感言
2014/01/10 职场文书
培养联系人考察意见
2015/06/01 职场文书
国情备忘录观后感
2015/06/04 职场文书
婚宴致辞
2015/07/28 职场文书
python 如何做一个识别率百分百的OCR
2021/05/29 Python
解决xampp安装后Apache无法启动
2022/03/21 Servers
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android
原生JS实现分页
2022/04/19 Javascript
Python内置类型集合set和frozenset的使用详解
2022/04/26 Python
Android Studio实现带三角函数对数运算功能的高级计算器
2022/05/20 Java/Android