剖析并且自己手动编写javascript API


自己手动编写jsApi

1.用es5实现数组的map方法

1
2
3
4
5
6
7
8
Array.prototype.myMap = (fn, context) => {
let mappedArr = [];
let arr = Array.prototype.slice.call(this);
for(let i = 0; i < arr.length; i++) {
mappedArr.push(fn.call(context, arr[i], i, this));
}
return mappedArr;
}

2.用es5实现数组的reduce方法

1
2
3
4
5
6
7
8
9
Array.prototype.myReduce = (fn, initialValue) => {
let arr = Array.prototype.slice.call(this);
let res = initialValue ? initialValue : arr[0];
let startIndex = initialValue ? 0 : 1;
for(let i = startIndex; i < arr.length; i++) {
res = fn.call(null, res, arr[startIndex]);
}
return mappedArr;
}

3.实现call/apply

1
2
3
4
5
6
7
8
9
// 实现apply只要把下面的...args 换成 args
Function.prototype.myCall = (context = window, ...args) => {
let func = this;
let fn = Symbol('fn');
context[fn] = func;
let res = context[fn](...args"fn"); // 相当于 context.caller(...args);
delete context[fn];
return res;
}

4.实现对象的Object.create()方法

1
2
3
4
5
6
Object.create = (proto) => {
function F() {};
F.prototype = proto;
F.prototype.constructor = F;
return new F();
}

5.实现bind方法

1
2
3
4
5
6
7
8
Function.prototype.myBind = (context, ...args) => {
let self = this;// 谨记this指向调用bind的函数
let fBound = function() {
return self.apply(this instanceof fBound ? this : context || window, args);
}
fBound.prototype = object.create(this.prototype); // 保证函数原型上的属性不丢失
return fBound;
}

6.实现new关键字

1
2
3
4
5
function myNew(fn, ...args) {
let instance = Object.create(fn.prototype);
let res = fn.apply(instance, args);
return typeof res === 'object' ? res : instance;
}

7.实现instanceof的作用

1
2
3
4
5
6
7
8
function myInstanceof(left, right) {
let proto = Oject.getPrototypeOf(left);
while(true) {
if (proto === null) return false;
if (proto === right.prototype) return true;
proto = Oject.getProtypeOf(proto);
}
}

8.实现单例模式

1
2
3
4
5
6
7
8
9
10
11
12
function proxy() {
let instance;
let handler = {
constructor(target, args) {
if(!instance) {
instance = Reflect.contructor(fun, args);
}
return instance;
}
};
return new Proxy(func, handler);
}

`