_new 方法实现
/**
* 思路:
* 创建一个对象
* 对象.__proto__ = 构造函数.prototype
* 执行构造函数
*/
function _new(A, ...args) {
const o = {};
o.__proto__ = A.prototype;
const res = A.apply(this, args);
if(res && (typeof(res) === 'object' || typeof(res) === 'function'){
return res;
}
return o;
}
apply2
Function.prototype.apply2 = function (content = window) {
content.fn = this;
let result;
if (arguments[1]) {
result = content.fn(...arguments[1]);
} else {
result = content.fn();
}
delete content.fn;
return result;
}
;
call2 实现
Function.prototype.call2 = function (content = window) {
content.fn = this;
const args = [].slice(arguments, 1);
const result = content.fn(...args);
delete content.fn;
return result;
};
bind
/**
* 思路
* 1. 绑定this
* 2. 能接受参数
* 3. 返回一个绑定函数
* 4. 绑定函数能返回值
* 5. 绑定函数能使用new
* 6. 绑定函数new出来对象能继承原函数的属性
*/
Function.prototype.bind2 = function (context, ...args1) {
const self = this;
function fBound(...args2) {
return self.apply(this instanceof fBound ? this : context, [...args1, ...args2]);
}
function fNOP() {}
// 维护原型关系
if (this.prototype) {
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
};
const foo = {
value: 1
}
;
function bar(name, age) {
this.name = name;
this.age = age;
console.log(this.value);
}
bar.prototype.friend = 'kevin';
bar.prototype.getName = function () {
console.log(this.name);
};
const NewBar = bar.bind(foo, 'hpy');
// NewBar();
const obj = new NewBar(20);
console.log(obj);
console.log(obj.constructor);
// NewBar.prototype.friend = 'aaa'; // 修改绑定函数原型属性不会影响原函数的原型属性
// console.log(bar.prototype.friend);
// bind 当作构造器,bind的this就失效了,所以当构造器使用,没啥意义了。
curry
const curry = (fn, ...args1) =>
args1.length < fn.length
? (...args2) => curry(fn, ...args1, ...args2)
: fn(...args1);
instanceof
/**
* A 为实例
* B 为构造器
*/
function instanceof1(A, B) {
const O = B.prototype;
A = A.__proto__;
while (true) {
if (A === null) return false;
if (A === O) return true;
A = A.__proto__;
}
}
function F() {
}
const newF = new F();
console.log(instanceof1(newF, F));
debounce
/**
* 手写防抖(debounce)
* @param fn
* @param wait
* @return fun
* 思考:防抖-> 一定时间内只执行一次
* 利用clearTimeout清除setTimeout来实现
* 返回一个函数
*/
function debounce(fn, wait = 200) {
let timer;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, wait);
};
}
throttle
/**
* 函数节流
* throttle
* @param fn
* @param wait
*/
function throttle(fn, wait = 200){
let prev = new Date();
return function(...args){
const now = new Date();
if(now - prev > wait){
fn.apply(this, args);
prev = new Date();
}
}
}
add(1,2)(3,4) 无限累加
const sum = (...args) => args.reduce((total, num) => total + num, 0);
const add = (...args1) => {
const total = sum(...args1);
const temp = (...args2) => add(total, ...args2);
temp.toString = () => total;
return temp;
}
reduce实现map
Array.prototype.map1 = function(cb){
return this.reduce((res, cur, i) => res.concat(cb(cur, i, this)), []);
}