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 相关文章推荐
善用事件代理,警惕闭包的性能陷阱。
Jan 20 Javascript
Javascript字符串对象的常用方法简明版
Jun 26 Javascript
javascript面向对象之共享成员属性与方法及prototype关键字用法
Jan 13 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
Feb 27 Javascript
Vuex简单入门
Apr 19 Javascript
Vuex之理解Store的用法
Apr 19 Javascript
Angular 4环境准备与Angular cli创建项目详解
May 27 Javascript
基于jQuery的表单填充实例
Aug 22 jQuery
小白教程|一小时上手最流行的前端框架vue(推荐)
Apr 10 Javascript
vue将后台数据时间戳转换成日期格式
Jul 31 Javascript
mpvue实现小程序签到金币掉落动画(api实现)
Oct 17 Javascript
Vue如何获取数据列表展示
Dec 11 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框架的性能
2008/01/10 PHP
PHP自动补全表单的两种方法
2017/03/06 PHP
Laravel框架控制器,视图及模型操作图文详解
2019/12/04 PHP
初识javascript 文档碎片
2010/07/13 Javascript
js中call与apply的用法小结
2013/12/28 Javascript
js继承call()和apply()方法总结
2014/12/08 Javascript
js运动动画的八个知识点
2015/03/12 Javascript
原生javascript实现解析XML文档与字符串
2016/03/01 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
vue元素实现动画过渡效果
2017/07/01 Javascript
对于js垃圾回收机制的理解
2017/09/14 Javascript
React/Redux应用使用Async/Await的方法
2017/11/16 Javascript
详解Angular5 服务端渲染实战
2018/01/04 Javascript
Vue 使用中的小技巧
2018/04/26 Javascript
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
vue实现文字加密功能
2019/09/27 Javascript
js中apply和call的理解与使用方法
2019/11/27 Javascript
vue 自定义组件的写法与用法详解
2020/03/04 Javascript
详解vue路由
2020/08/05 Javascript
[01:50]WODOTA制作 DOTA2中文宣传片《HERO》
2013/04/28 DOTA
Python学习笔记(二)基础语法
2014/06/06 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
python调用外部程序的实操步骤
2019/03/04 Python
Python使用MyQR制作专属动态彩色二维码功能
2019/06/04 Python
python 图像处理画一个正弦函数代码实例
2019/09/10 Python
Python全面分析系统的时域特性和频率域特性
2020/02/26 Python
Selenium alert 弹窗处理的示例代码
2020/08/06 Python
CSS3弹性盒模型开发笔记(一)
2016/04/26 HTML / CSS
瑜伽服装品牌:露露柠檬(lululemon athletica)
2017/06/04 全球购物
世界首屈一指的在线男士内衣权威:HisRoom
2017/08/05 全球购物
上班早退检讨书
2014/01/09 职场文书
大学生创业计划书怎么写
2014/09/15 职场文书
在校学生证明格式
2015/06/24 职场文书
2015年国庆节新闻稿
2015/07/18 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书
利用python做数据拟合详情
2021/11/17 Python