new实现
- 创建一个对象
- 将构造函数的作用域赋给新对象
- 给新对象添加属性
- 返回新对象
function MyNew() {
let newObj = {},
targetConstructor = [].shift.call(arguments);
newObj = Object.create(targetConstructor.prototype);
const ret = targetConstructor.apply(newObj, arguments);
return typeof ret === "object" ? ret || newObj : newObj;
}
call
- 将函数设为对象的属性
- 执行该函数
- 从对象上删除该函数
Function.prototype.myCall = function (context = window) {
context.fn = this;
const args = [];
for (let i = 1, len = arguments.length; i < len; i++) {
args.push("arguments[" + i + "]");
}
const result = eval("context.fn(" + args + ")");
delete context.fn;
return result;
};
apply
Function.prototype.myApply = function (context = window, arr) {
context.fn = this;
let result;
if (!arr) {
result = context.fn();
} else {
for (let i = 0, len = arr.length; i < len; i++) {
args.push("arr[" + i + "]");
}
result = eval("context.fn(" + args + ")");
}
delete context.fn;
return result;
};
bind
- bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。(来自于 MDN )
- 传入一个绑定的对象和参数
- 返回一个函数
Function.prototype.myBind = function (context) {
const self = this;
const argument = [].slice.call(arguments, 1);
let fBind = function () {
const args = [].slice.call(arguments);
self.apply(this instanceof fBind ? this : context, argument.concat(args));
};
const fNOP = function () {};
fNOP.prototype = this.prototype;
fBind.prototype = new fNOP();
return fBind;
};
var foo = {
value: 1,
};
function bar(name, age) {
this.habit = "shopping";
console.log(this.value, "实例化的时候,无法获取到该值");
console.log(name);
console.log(age);
}
bar.prototype.friend = "kevin";
var bindFoo = bar.myBind(foo, "daisy");
const obj = new bindFoo("18");
console.log(obj.friend);
console.log(obj.habit);
参考资料
再此感谢冴羽大佬的深入系列