手写call
Function.prototype.newCall = function(context, ...args) {
if (typeof context === 'undefined' || context === null) {
context = window
}
context.fn = this;
context.fn(...args);
delete context.fn;
}
let foo = {
value: 100
};
function bar(name) {
console.log(this.value);
}
bar.newCall(foo);
手写apply
Function.prototype.newApple = function(context, args = []) {
if (typeof context === 'undefined' || context === null) {
context = window
}
context.fn = this;
context.fn(args);
delete context.fn;
}
let foo = {
value: 100
};
function bar(arr) {
console.log(this.value);
console.log('arr',arr);
}
bar.newApple(foo,['1','2','3']);
手写bind
Function.prototype.newBind = function(context, ...args) {
if (context == null) {
context = window
}
if (typeof context !== 'object') {
context = Object(context)
}
const that = this
return function(...innerArgs) {
return that.apply(context, [...args, ...innerArgs])
}
}
let foo = {
value: 100
};
function bar(arr) {
console.log(this.value);
console.log('arr',arr);
}
var livebind = bar.newBind(foo, ['1','2','3'])
livebind()
手写new
function Person (name, age) {
this.name = name;
this.age = age;
}
function newObj(context, ...args) {
console.log('...args',args)
var obj = {};
obj.__proto__ = context.prototype;
context.apply(obj, args);
return obj;
};
var person = newObj(Person, 'live', '18')
console.log(person.name)
console.log(person.age)
手写Promise
class MyPromise {
constructor(live) {
this.initValue();
this.initBind();
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
try {
live(this.resolve, this.reject);
} catch (error) {
this.reject(error);
}
}
initValue() {
this.PromiseResult = null;
this.PromiseState = "pending";
}
resolve(value) {
if (this.PromiseState !== "pending") return;
this.PromiseState = "fulfilled";
this.PromiseResult = value;
this.onFulfilledCallbacks.forEach((fn) => fn(value));
}
reject(reason) {
if (this.PromiseState !== "pending") return;
this.PromiseState = "rejected";
this.PromiseResult = reason;
this.onRejectedCallbacks.forEach((fn) => fn(reason));
}
initBind() {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (value) => value;
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
throw reason;
};
return new MyPromise((resolve, reject) => {
const handlePromise = (fn, value) => {
setTimeout(() => {
try {
const result = fn(value);
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
});
};
if (this.PromiseState === "fulfilled") {
handlePromise(onFulfilled, this.PromiseResult);
} else if (this.PromiseState === "rejected") {
handlePromise(onRejected, this.PromiseResult);
} else if (this.PromiseState === "pending") {
this.onFulfilledCallbacks.push(() => {
handlePromise(onFulfilled, this.PromiseResult);
});
this.onRejectedCallbacks.push(() => {
handlePromise(onRejected, this.PromiseResult);
});
}
});
}
}
const test1 = new MyPromise((resolve, reject) => {
resolve("test1");
})
.then((res) => {
console.log("then1", res);
})