首先在Function的原型对象上定义一个method方法,本文贯彻始终都会用到这个方法,该方法定义如下:
Function.prototype.method = function(name,func){
this.prototype[name] = func;
return this;
}
数组方法
splice方法
Array.method('splice', function(start, deleteCount){
var max = Math.max,
min = Math.min,
delta,
element,
insertCount = max(arguments.length - 2, 0),
k = 0,
len = this.length,
new_len,
result = [],
shift_count;
start = start || 0;
if (start < 0) {
start += len;
}
start = max(min(start, len), 0);
deleteCount = max(min(typeof deleteCount === 'number' ? deleteCount : len, len - start), 0);
delta = insertCount - deleteCount;
new_len = len + delta;
while (k < deleteCount) {
element = this[start + k];
if (element !== undefined) {
result[k] = element;
}
k += 1;
}
shift_count = len - start - deleteCount;
if (delta < 0) {
k = start + insertCount;
while (shift_count) {
this[k] = this[k - delta];
k += 1;
shift_count -= 1;
}
this.length = new_len;
} else if (delta > 0) {
k = 1;
while (shift_count) {
this[new_len - k] = this[len - k];
k += 1;
shift_count -= 1;
}
}
for (k = 0; k < insertCount; k += 1) {
this[start + k] = arguments[k + 2];
}
return result;
})
pop方法
Array.method('pop', function(){
return this.splice(this.length - 1, 1)[0];
})
push方法
Array.method('push', function(){
this.splice.apply(this,[this.length, 0].concat(Array.prototype.slice.apply(arguments)));
return this.length;
})
shift方法
Array.method('shift', function(){
return this.splice(0,1)[0];
})
unshift方法
Array.method('unshift', function(){
this.splice.apply(this, [0, 0].concat(Array.prototype.slice.apply(arguments)));
return this.length;
})
filter方法
Array.method('filter', function(callback){
if (Object.prototype.toString.call(this) !== '[object Array]' || !this.length || typeof callback !== 'function') {
return [];
} else {
const result = [];
for (let i = 0; i < this.length; i++) {
const item = this[i];
if (callback(item, i, this)) {
result.push(item);
}
};
return result;
}
})
find方法
Array.method('find', function(callback){
if (Object.prototype.toString.call(this) !== '[object Array]' || !this.length || typeof callback !== 'function') {
return;
} else {
for (let i = 0; i < this.length; i++) {
const item = this[i];
if (callback(item,i,this)) {
return item;
}
}
}
})
findIndex方法
Array.method('findIndex', function(callback){
if (Object.prototype.toString.call(this) !== '[object Array]' || !this.length || typeof callback !== 'function') {
return;
} else {
for (let i = 0; i < this.length; i++) {
const item = this[i];
if (callback(item, i, this)) {
return i;
}
}
}
})
map方法
Array.method('map', function(callback){
// 处理数组类型异常
if(this === null || this === undefined) {
throw new TypeError("Cannot read property 'map' of null or undefined");
};
if(Object.prototype.toString.call(callback) !== '[object Function]'){
throw new TypeError(callback + "is not a function");
};
const result = [];
for(let i = 0; i < this.length; i++) {
const item = this[i];
const newItem = callback(item, i, this);
result.push(newItem);
}
return result;
})
函数方法
call方法
call方法的简单实现
Function.method('call',function(obj, ...args){
const fn = Symbol();
obj[fn] = this;
obj[fn](...args);
delete obj[fn];
})
apply方法
apply方法的简单实现:apply方法几乎和call方法一样,不同的是apply方法传入的是一个数组
Function.method('apply',function(obj,args){
const fn = Symbol();
obj[fn] = this;
obj[fn](...args);
delete obj[fn];
})
bind方法
Function.method('bind', function(that){
//返回一个函数,调用这个函数就像它是那个对象的方法一样
const method = this,
slice = Array.prototype.slice,
args = slice.apply(arguments, [1]);
return function(){
return method.apply(that, args.concat(slice.apply(arguments, [0])))
}
})
参考资料:javaScript语言精髓