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编写COM组件的步骤
Mar 17 Javascript
JQuery Ajax通过Handler访问外部XML数据的代码
Jun 01 Javascript
javascript jq 弹出层实例
Aug 25 Javascript
js添加select下默认的option的value和text的方法
Oct 19 Javascript
js插件dropload上拉下滑加载数据实例解析
Jul 27 Javascript
BootStrap的table表头固定tbody滚动的实例代码
Aug 24 Javascript
微信小程序开发之圆形菜单 仿建行圆形菜单实例
Dec 12 Javascript
vue中v-model动态生成的实例详解
Oct 27 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
Sep 20 Javascript
javascript关于“时间”的一次探索
Jul 24 Javascript
Vue 动态组件components和v-once指令的实现
Aug 30 Javascript
javascript设计模式之迭代器模式
Jan 30 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
Symfony2开发之控制器用法实例分析
2016/02/05 PHP
PHP性能优化大全(php.ini)
2016/05/20 PHP
thinkphp中U方法按路由规则生成url的方法
2018/03/12 PHP
PHP lcfirst()函数定义与用法
2019/03/08 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
2012/06/22 Javascript
JavaScript的strict模式与with关键字介绍
2014/02/08 Javascript
三种方式获取XMLHttpRequest对象
2014/04/21 Javascript
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
2016/06/02 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
Node.js使用orm2进行update操作时关联字段无法修改的解决方法
2017/06/13 Javascript
使用async await 封装 axios的方法
2018/07/09 Javascript
解决bootstrap-select 动态加载数据不显示的问题
2018/08/10 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
2018/10/11 Javascript
vue头部导航动态点击处理方法
2018/11/02 Javascript
在 Angular-cli 中使用 simple-mock 实现前端开发 API Mock 接口数据模拟功能的方法
2018/11/28 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
vue安装遇到的5个报错及解决方法
2019/06/12 Javascript
加速vue组件渲染之性能优化
2020/04/09 Javascript
Python3实现的画图及加载图片动画效果示例
2018/01/19 Python
PyQt5实现无边框窗口的标题拖动和窗口缩放
2018/04/19 Python
Django实现分页功能
2018/07/02 Python
python装饰器的特性原理详解
2019/12/25 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
2020/03/05 Python
最新版 Windows10上安装Python 3.8.5的步骤详解
2020/11/28 Python
10个顶级Python实用库推荐
2021/03/04 Python
澳大利亚个性化儿童礼品网站:Bright Star Kids
2019/06/14 全球购物
Prototype如何为一个Ajax添加一个参数
2015/12/06 面试题
化学相关工作求职信
2013/10/02 职场文书
最新的互联网创业计划书
2014/01/10 职场文书
2014年电厂工作总结
2014/12/04 职场文书
5种方法告诉你如何使JavaScript 代码库更干净
2021/09/15 Javascript