JS原生实现API
Array
1、forEach
Array.prototype.mockForEach = function(callback) {
for(let i = 0;i<this.length;i++){
callback(this[i],i,this)
}
}
2 、map
Array.prototype.mockMap = function(callback){
const mapArr = [];
for(let i = 0;i<this.length;i++){
mapArr.push(callback(this[i],i,this))
}
return mapArr
}
3、filter
Array.prototype.mockFilter = function(callback){
const filterArr = [];
for(let i = 0;i<this.length;i++){
callback(this[i],i,this) && filterArr.push(this[i])
}
return filterArr
}
4、every
Array.prototype.mockEvery = function(callback){
let flag = true;
for(let i = 0;i<this.length;i++){
flag = callback(this[i],i,this)
if(!flag) break
}
return flag
}
5、some
Array.prototype.mockSome = function(callback){
let flag = false;
for(let i = 0;i<this.length;i++){
flag = callback(this[i],i,this)
if(flag) break;
}
return flag
}
6、reduce
Array.prototype.mockReduce = function(callback,initValue){
let start = 0; //如果没有initValue,则从数组第一个元素充当,并从第二个元素开始遍历
let pre;
if(initValue){
pre = initValue
}else{
pre = this[0];
start = 1;
}
for(let i = 0;i<this.length;i++){
pre = callback(pre,this[i],i,this)
}
return pre;
}
7、findIndex
Array.prototype.mockFindIndex = function(callback){
for(let i = 0;i<this.length;i++){
if(callback(this[i],i,this)){
return i;
}
}
return -1 //找不到要返回-1
}
8、find
Array.prototype.mockFind = function(callback){
for(let i = 0;i<this.length;i++){
if(callback(this[i],i,this)){
return this[i]
}
}
return undefined;
}
9、fill
Array.prototype.mokeFill = function(value,start = 0,end){
end = end || this.length;
for(let i = start;i<end;i++){
this[i] = value;
}
return this
}
10、includes
用处:查找元素,查到返回true
,反之返回false
,可查找NaN
Array.prototype.mockIncludes = function(value,start = 0){
if(start<0) start = start + this.length
const isNaN = Number.isNaN(value)
for(let i = start;i<this.length;i++){
if(this[i] === value || Number.isNaN(this[i])=== isNaN){
return true
}
}
return false
}
11、join
Array.prototype.mockJoin = function(breakSign = ','){
let str = '';
for(let i = 0;i<this.length;i++){
str = i === 0?`${str}${this[i]}`:`${str}${breakSigh}${this[i]}`
}
return str
}
12、flat
Array.prototype.mockFlat = function(num = 1){
if(!Number(num) || Number(num)<0){
return this
}
let flatArr = [];
for(let i = 0;i<this.length;i++){
if(Array.isArray(this[i])){
flatArr = flatArr.concat(this[i].mockFlat(--num))
}else{
flatArr.push(this[i])
}
}
return flatArr
}
13、splice
顺序:
1、拷贝删除的元素
2、挪动删除元素后面的元素
3、如果有插入操作,插入新元素
Array.prototype.mockSplice = function(start,cutOutLength,...values){
const spliceArr = [];
const backUpArr = [...this]
start = start < 0 ? this.length - 1 + start : start
//拷贝获取裁剪的元素
for(let i = start;i<start+cutOutLength;i++){
spliceArr[i - start] = backUpArr[i];
}
//挪动删除元素后面的元素
//1、删除的长度比插入长(向前挪)
if(cutOutLength > values.length){
for(let move = start + cutOutLength;move<this.length;move++){
let moveForm = move;
let moveTo = move - (cutOutLength - values.length)
if(moveForm in this){
this[moveTo] = this[moveForm]
}else{
delete this[moveTo]
}
}
}else if(cutOutLength < values.length){
//2、插入的长度比删除的长(向后挪)
for(let move = this.length-1;move>= start + cutOutLength ;move--){
let moveForm = move;
let moveTo = move + (values.length - cutOutLength);
if(moveForm in this){
this[moveTo] = this[moveForm]
}else{
delete this[moveTo]
}
}
}
//插入新元素
for(let add = 0;add < values.length;add++){
this[start + add] = values[add];
}
return spliceArr
}
Object
1、fromEntries
用处:跟entries
相反,将键值对数组转成对象
Object.prototype.mockfromEntries = function(arr){
const fromEntriesObj = {}
for(let i = 0;i<arr.length;i++){
const [key,value] = arr[i];
obj[key] = value
}
return fromEntriesObj
}
2、entries
用处:将对象转成键值对数组
注意点:for in会查找到原型链上,所以要做hasOwnProperty的判断
Object.prototype.mockEntries = function(obj){
const entriesArr = []
const keyArr = Object.getOwnPropertyNames(obj);
if(keyArr.length){
for(let i = 0;i<keyArr.length;i++){
entriesArr.push([keyArr[i],obj[keyArr[i]]])
}
}
return entriesArr
}
3、keys
Object.prototype.mockKeys = function(obj){
const keysArr = Object.getOwnPropertyNames(obj);
return keysArr
}
4、values
Object.prototype.mockValues = function(obj){
const valuesArr = [];
const keysArr = Object.getOwnPropertyNames(obj)
for(let i = 0; i<keysArr.length;i++){
valuesArr.push(obj[keysArr[i]])
}
return valuesArr
}
5、instanceOf
实例于
function mockInstanceOf(child,father){
const grandFather = father.prototype
child = child.__proto__
while(true){
if(child === null){
return false;
}
if(grandFather === child){ //如果实例元素的祖先有
return true;
}
child = child.__proto__ //遍历实例元素
}
}
6、assign
Object.prototype.mockAssign = function(target,...args){
if(target === null || target === undefined){
throw new TypeError('Cannot convert undefined or null to object')
}
mockTarget = Object(target)
for (let nextObj of args) {
for (let key in nextObj) {
nextObj.hasOwnProperty(key) && (mockTarget[key] = nextObj[key])
}
}
return mockTarget
}
Function
1、call
用处:改变this的指向
思路:当obj.fn被执行时,fn的this指向obj,从而修改this的指向
Function.prototype.mockCall = function(context = window,...args){
//保证fn的唯一
const fn = Symbol()
//保证context为对象
context = context instanceof Object ? context : {};
context.fn = this //将需要修改this的方法赋值给ctx.fn, 当这个方法执行,则this就会指向ctx
const calledFunction = context.fn(...args)
// 避免污染context,使用完需要删除该属性
delete context.fn
return calledFunction
}
2、apply
用处:改变this指向,但是参数以数组的形式传入
思路:同上
Function.prototype.mockApply = function(context = window,arg){
//保证fn的唯一
const fn = Symbol()
//保证context为对象
context = context instanceof Object ? context : {};
context.fn = this //将需要修改this的方法赋值给ctx.fn, 当这个方法执行,则this就会指向ctx
const applyFunction = context.fn(...arg)
// 避免污染context,使用完需要删除该属性
delete context.fn
return applyFunction
}
3、bind
用处:返回一个绑定函数,并将方法的this指向这个函数
Function.prototype.mockBind = function(context = window){
return (...args)=>{this.call(obj,...args)}
}
String
1、slice
String.prototype.mockSlice = function(start = 0,end){
start = start < 0 ? this.length + start : start
end = !end && end !== 0 ? this.length : end
if(start >= end) return '';
let sliceStr = ''
for(let i = start;i<end;i++){
sliceStr += this[i]
}
return sliceStr
}
2、substr
String.prototype.mockSubstr = function(start = 0,length){
if(length<0) return '';
start = start < 0 ? this.length + start : start;
length = (!length && length !== 0) || length > this.length - start ? this.length : start + length
let str;
for(let i = 0;i<length;i++){
str += this[i]
}
return str;
}
3、substring
String.prototype.mockSubString = function(start = 0,end){
start = start < 0 ? this.length + start : start
end = !end && end !== 0 ? this.length : end
if (start >= end) [start, end] = [end, start]
let subStringStr = ''
for (let i = start; i < end; i++) {
str += this[i]
}
return subStringStr
}