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 兼容FF的onmouseenter和onmouseleave的代码
Jul 19 Javascript
Dom 学习总结以及实例的使用介绍
Apr 24 Javascript
jQuery学习笔记之2个小技巧
Jan 19 Javascript
javascript实现Table排序的方法
May 15 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
May 09 Javascript
jQuery实现菜单栏导航效果
Aug 15 jQuery
详解如何使用webpack在vue项目中写jsx语法
Nov 08 Javascript
node.js利用socket.io实现多人在线匹配联机五子棋
May 31 Javascript
Vue2.0点击切换类名改变样式的方法
Aug 22 Javascript
微信小程序使用scroll-view标签实现自动滑动到底部功能的实例代码
Nov 09 Javascript
Vue强制组件重新渲染的方法讨论
Feb 03 Javascript
js实现简易ATM功能
Oct 27 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
DOM XPATH获取img src值的query
2013/09/23 PHP
Yii框架参数化查询中IN查询只能查询一个的解决方法
2017/05/20 PHP
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
2011/05/25 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
2013/08/08 Javascript
基于JavaScript实现TAB标签效果
2016/01/12 Javascript
浅谈javascript:两种注释,声明变量,定义函数
2016/10/05 Javascript
javascript删除html标签函数cIsHTML
2017/01/09 Javascript
jquery实现自定义图片裁剪功能【推荐】
2017/03/08 Javascript
详解JavaScript按概率随机生成事件
2017/08/02 Javascript
Vue 滚动行为的具体使用方法
2017/09/13 Javascript
vue.js2.0点击获取自己的属性和jquery方法
2018/02/23 jQuery
vue 表单验证按钮事件交由父组件触发的方法
2018/12/17 Javascript
react-router4按需加载(踩坑填坑)
2019/01/06 Javascript
Node.js 多进程处理CPU密集任务的实现
2019/05/26 Javascript
JavaScript简单编程实例学习
2020/02/14 Javascript
Javascript模块化机制实现原理详解
2020/04/02 Javascript
js抽奖转盘实现方法分析
2020/05/16 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
python中list循环语句用法实例
2014/11/10 Python
Python常见工厂函数用法示例
2018/03/21 Python
使用python获取(宜宾市地震信息)地震信息
2019/06/20 Python
Tensorflow 多线程设置方式
2020/02/06 Python
ubuntu16.04升级Python3.5到Python3.7的方法步骤
2020/08/20 Python
Python3 pyecharts生成Html文件柱状图及折线图代码实例
2020/09/29 Python
Python代码覆盖率统计工具coverage.py用法详解
2020/11/25 Python
Python 微信公众号文章爬取的示例代码
2020/11/30 Python
基于HTML5的WebSocket的实例代码
2018/08/15 HTML / CSS
HomeAway的巴西品牌:Alugue Temporada
2018/04/10 全球购物
美国农场鲜花速递:The Bouqs
2018/07/13 全球购物
介绍一下EJB的分类及其各自的功能及应用
2016/08/23 面试题
《晏子使楚》教学反思
2014/02/08 职场文书
《九寨沟》教学反思
2014/04/08 职场文书
Shell脚本一键安装Nginx服务自定义Nginx版本
2022/03/20 Servers
MySQL池化框架学习接池自定义
2022/07/23 MySQL