//类的this指针使用
class Log{
constructor() {
//为printX函数绑定当前类对象,解决调用this.print时找不到print方法
this.printX = this.printX.bind(this);
//通过箭头函数形式使this指针自动绑定方法
this.printY = ((y='y') => {
this.print(`this allow auto bind this,${y}`);
});
}
print(obj){
console.log(obj);
}
printX(x='a'){
this.print(`hi,${x}`);//使用了this指针
}
printY(x='a'){
this.print(`bind test :,${x}`);//使用了this指针
}
}

let l = new Log();
l.printX('HELLO');//可正常调用
//导出形式调用报错
const {printX,printY}=l;//从对象中导出
//printX调用的print方法找不到,this失效
//printX('WOW');//Cannot read properties of undefined (reading 'print')
//通过绑定this的形式解决,上面的构造函数中添加了函数绑定this对象
console.log('printX方法已绑定this指针,问题解决');
printX('WOW');
console.log('printY方法通过箭头函数自动绑定this指针,问题解决');
printY('===world===');

//通过代理器在获取函数方法时自动绑定this
function proxyAutoBindThis(obj){
let c = new WeakMap();//缓存
//代理器处理事件
let h = {
get (t,k){
let v = Reflect.get(t,k);
if (typeof v!=='function'){return v;}//不是函数不处理,直接返回
if (!c.has(v)){c.set(v,v.bind(t));}//不重复绑定
return c.get(v);//返回绑定了this的函数
}
};
let p = new Proxy(obj,h);//为传入的obj设置代理器
return p;//返回代理器对象
}

class A{
test(obj){
console.log(obj);
}
test1(obj=null){
this.test(`${obj}===>,test1`);//使用this指针
}
test2(obj=null){
this.test(`${obj}===>,test2`);//使用this指针
}
}
let a = new A();//实例化A对象a
let objBindThisByProxy = proxyAutoBindThis(a);//所有方法自动绑定this
let {test1,test2}=objBindThisByProxy;//从代理器导出
//类对象调用
a.test1('类对象调用');
a.test2('类对象调用');
//通过代理器调用
test1('通过代理器调用');
test2('通过代理器调用');