gpt告诉我,Java中的方法中的this始终指向于该方法所属的类的对象,这样可以保证一个方法始终只能被一个类所调用,譬如定义一个蟹堡王,它有一个名叫制作蟹黄堡的方法,那么,java中不存在这样的句子
const 制作汉堡 = 蟹堡王.制作蟹黄堡;
const 来路不正的蟹黄堡 = 痞老板.制作汉堡();
可惜的是,js中是允许上述操作的,通过apply,bind等,由此,在class语法中存在一些需要注意的点;
在class语法中声明方法的方式是存在区别的:
class A{
method1(){
console.log('method1');
}
method2 = function(){
console.log('method2');
}
}
这段用到class语法的代码可以用下面的方式实现,
const A =(()=>{
function foo(){
this.method2= function(){
console.log('method2');
}
}
foo.prototype.method1 = function(){
console.log('method1');
}
return foo;
})();
于是我们会发现一个问题,如果用method2=function()这样的方法实现,method2会被视为一个实例属性,于是每新建一个实例便会新建一个method2;而method1方法会直接成为原型对象的方法,相比之下内存性能更好;
引申出另一个问题,this的指向问题,如果我们希望制作蟹黄堡的一定是某个蟹堡王,我们可以用到箭头函数,即,在声明制作蟹黄堡这个方法时,作用域中的this应该是指向某个蟹堡王实例的;于是我们知道,制作蟹黄堡这个方法应该成为对象的方法而不是原型对象的方法,因为每个制作蟹黄堡方法的this指向了不同的蟹堡王实例:
class 蟹堡王{
制作蟹黄堡 = ()=>{
this.煎肉饼();
this.上酱料();t
his.合成汉堡();}
...
}
而如果用另一种写法,是无法声明箭头函数的方法的,因为在为某个类的原型对象声明一个方法时,当前作用域中的this是不能确定的;而如果方法本身是一个实例属性的话,由于实例属性总是在constructer中被赋值的,而constructer又总是被类的实例所调用的。
class 蟹堡王{
...
制作蟹黄堡 (){
this.煎肉饼();
this.上酱料();t
his.合成汉堡();
}
...
}
像上面这种写法,非蟹堡王的对象也能通过apply执行制作蟹黄堡方法;而如果希望制作蟹黄堡方法的this被固定的话,性能相比之下不怎么好的实例属性方法也许是可能的解决方案。