Function.prototype.MyCall = function (context) {
if (typeof this !== "function") {
throw new TypeError("this is not a function");
}
console.log(arguments, "arguments1");
const args = [...arguments].slice(1);
context = context || window;
const fnSymbol = Symbol()
context[fnSymbol] = this;
const result = context[fnSymbol](...args);
delete context[fnSymbol];
return result;
};
Function.prototype.MyApply = function (context) {
if (typeof this !== "function") {
throw new TypeError("this is not a function");
}
let result = null;
const fnSymbol = Symbol();
context[fnSymbol] = this;
if (arguments[1]) {
result = context[fnSymbol](...arguments[1]);
} else {
result = context[fnSymbol]();
}
delete context[fnSymbol]
return result;
};
const obj = {
value: "123",
};
function bar(name, age) {
console.log(name, age);
console.log(this.value, "value");
}
bar.MyCall(obj, '小明', 24);
bar.MyApply(obj, ['小明', 24]);
Function.prototype.MyBind = function (context) {
if (typeof this !== "function") {
throw new TypeError("this is not a function");
}
console.log(arguments, "MyBind");
const fn = this;
const args = [...arguments].slice(1);
const fNOP = function () {};
const fBound = function () {
console.log(arguments, "fBound");
return fn.apply(this instanceof fNOP ? this : context, [
...args,
...arguments,
]);
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
let value = 2;
let foo = {
value: 1,
};
function bar(name, age) {
this.habit = "shopping";
console.log(this.value);
console.log(name);
console.log(age);
}
bar.prototype.friend = "kevin";
let bindFoo = bar.MyBind(foo, "xaioming");
bindFoo(10);
let bindFoo1 = bar.MyBind(foo, "Jack");
let obj1 = new bindFoo1(20);
console.log(obj1.habit, "obj1.habit");
console.log(obj1.friend, "obj1.friend");
1. 首先创建一个新的空对象。
2. 根据原型链,设置空对象的 `__proto__` 为构造函数的 `prototype` 。
3. 构造函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)。
4. 判断函数的返回值类型,如果是引用类型,就返回这个引用类型的对象,否则返回这个对象。
function MyNew(context) {
const obj = {};
obj.__proto__ = context.prototype;
const res = context.apply(obj, [...arguments].slice(1));
return typeof res === "object" ? res : obj;
}
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const car1 = MyNew(Car, "Eagle", "Talon TSi", 1993);
console.log(car1.make);
console.log(car1.model);
console.log(car1.year);