bind的实现:
Function.prototype.bind2 = function(oThis){
if(typeof this !== 'function'){
throw new TypeError('被绑定的对象需要是函数')
}
var self = this
var args = [].slice.call(arguments, 1)
fBound = function(){ //this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
return self.apply(this instanceof fBound ? this : oThis, args.concat([].slice.call(arguments)))
}
var func = function(){}
//维护原型关系
if(this.prototype){
func.prototype = this.prototype
}
//使fBound.prototype是func的实例,返回的fBound若作为new的构造函数,新对象的__proto__就是func的实例
fBound.prototype = new func()
return fBound
}
new的实现:
function new2(){
debugger
//创建一个空对象
let obj = new Object();
//获取构造函数
let Constructor = [].shift.call(arguments);
//链接到原型
obj.__proto__ = Constructor.prototype;
//绑定this值
let result = Constructor.apply(obj,arguments);//使用apply,将构造函数中的this指向新对象,这样新对象就可以访问构造函数中的属性和方法
//返回新对象
return typeof result === "object" ? result : obj;//如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象
}
调用自定义的bind和new可以得到
function a() {console.log(this)}
const b = a.bind2({name: 'xxx'})
b(); // {name: 'xxx'}
new2 b(); // 返回a, bind不能改变new的this指向
网友评论