ES5中常见数组方法的实现,记录于此,如有疑问,欢迎指正。
forEach
Array.prototype.forEach = function (cb, context) {
if(this == null){
throw new TypeError('this is null or not defined')
}
if(typeof cb !== 'function'){
throw new TypeError(cb + ' is not a function')
}
let O = Object(this), k = 0, len = O.length >>> 0;
while(k < len){
if(k in O){
cb.call(context, O[k], k, O)
}
k++
}
}
reduce
Array.prototype.reduce = function(cb, initVal){
if(this == null){
throw new TypeError('this is null or not defined')
}
if(typeof cb !== 'function'){
throw new TypeError(cb + ' is not a function')
}
let O = Object(this), len = O.length >>> 0;
if(arguments.length === 1 && len === 0) throw new TypeError('Reduce of empty array with no initial value')
let acc, k = 0;
if(arguments.length >= 2){
acc = arguments[1]
}else{
// 稀疏数组
while(true){
if(k in O){
acc = O[k++];
break;
}
if(++k >= len) throw new TypeError('Reduce of empty array with no initial value')
}
}
while(k < len){
if(k in O){
acc = cb.call(undefined, acc, O[k], k, O)
}
k++
}
return acc
}
map
Array.prototype.map = function(cb, context){
if(this == null){
throw new TypeError('this is null or not defined')
}
if(typeof cb !== 'function'){
throw new TypeError(cb + ' is not a function')
}
let O = Object(this), len = O.length >>> 0, k = 0;
let result = new Array(len);
while(k < len){
if(k in O){
result[k] = cb.call(context, O[k], k, O)
}
k++
}
return result
}
filter
Array.prototype.filter = function(cb, context){
if(this == null){
throw new TypeError('this is null or not defined')
}
if(typeof cb !== 'function'){
throw new TypeError(cb + ' is not a function')
}
let O = Object(this), len = O.length >>> 0, k = 0;
let result = [];
while(k < len){
if(k in O){
let val = O[k]
if(cb.call(context, val, k, O)){
result.push(val)
}
}
k++
}
return result
}
every
Array.prototype.every = function(cb, context){
if(this == null){
throw new TypeError('this is null or not defined')
}
if(typeof cb !== 'function'){
throw new TypeError(cb + ' is not a function')
}
let O = Object(this), len = O.length >>> 0, k = 0;
while(k < len){
if(k in O){
if(!cb.call(context, O[k], k, O)){
return false
}
}
k++
}
return true
}
some
Array.prototype.some = function(cb, context){
if (this == null) {
throw new TypeError('this is null or not defined')
}
if (typeof cb !== 'function') {
throw new TypeError(cb + ' is not a function')
}
let O = Object(this), len = O.length >>> 0, k = 0;
while(k < len){
if(k in O && cb.call(context, O[k], k, O)){
return true
}
k++
}
return false
}
indexOf
Array.prototype.indexOf = function(target, start){
if(this == null){
throw new TypeError('this is null or not defined')
}
let O = Object(this), len = O.length >>> 0, k = 0;
if(len === 0) return -1;
if(isNaN(start)){
start = 0
}else if(start !== 0 && start !== (1/0) && start !== -(1/0)){
start = (start > 0 || -1) * Math.floor(Math.abs(start))
}
if(start > len) return -1
k = start >= 0? start : Math.max(len - Math.abs(start))
while(k < len){
if(k in O && O[k] === target){
return k
}
k++
}
return -1
}
lastIndexOf
Array.prototype.lastIndexOf = function(target, start){
if(this == null){
throw new TypeError('this is null or not defined')
}
let O = Object(this), len = O.length >>> 0;
if(len === 0) return -1
start = len
if(arguments.length > 1){
start = Number(arguments[1])
if(start !== start){
start = 0
}else if(start !== 0 && start !== (1/0) && start !== -(1/0)){
start = (start > 0 | -1) * Math.floor(Math.abs(start))
}
}
let k = start >= 0? Math.min(start, len - 1) : len - Math.abs(start)
for(;k >=0; k--){
if(k in O && O[k] === target){
return k
}
}
return -1
}
篇二,以上。