提问人:MOHAMED SIKKANDAR AFZAL M 提问时间:7/24/2023 最后编辑:MOHAMED SIKKANDAR AFZAL M 更新时间:7/25/2023 访问量:93
JavaScript 类中的相同方法或变量名称的行为不同
same method or variable name in a javascript class behaves differently
问:
class Parent{
method(){
console.log("Parent");
}
}
class Child extends Parent{
method(){
console.log("Parent");
}
}
var child = new Child();
console.log(child.method);
子类中的控制台返回方法,这是预期的行为。
class Parent{
method = "sss"
}
class Child extends Parent{
method(){
console.log("Child")
}
}
var child = new Child();
console.log(child.method)
为什么控制台在 Parent 类中返回方法变量 - “sss” ?
答:
2赞
Quentin
7/24/2023
#1
来自 MDN
公共实例字段在基类的构造时(在构造函数主体运行之前)或在子类中返回 super() 之后)添加到实例中。
即,它屏蔽了方法,因为它是在构造函数运行时分配的。
child.method
是对象本身的属性(其值为字符串)。这掩盖了原型上的一个功能。method
下面的代码演示了。
您可以看到,在示例(您的代码)中,字符串值是其自身的属性,但您可以挖掘原型链以从类中获取函数值。a
method
child
在示例中(删除了公共实例字段),该方法存在并且可以调用,但不在本身上(因为它是类的实例,因此它可以自动搜索原型链,因为它没有被屏蔽)。b
child
const a = () => {
class Parent {
method = "sss"
}
class Child extends Parent {
method() {
console.log("Child")
}
}
var child = new Child();
console.log("a: " + child.hasOwnProperty('method'));
Object.getPrototypeOf(child).method();
};
a();
const b = () => {
class Parent {}
class Child extends Parent {
method() {
console.log("Child")
}
}
var child = new Child();
console.log("b: " + child.hasOwnProperty('method'));
child.method();
};
b();
评论
0赞
codingStarter
7/24/2023
但它也发生在子类中——按照同样的原则,它应该发生在父亲字段之后?
0赞
Quentin
7/24/2023
方法不是公共实例字段。
1赞
codingStarter
7/24/2023
“方法只是一个属性”——这就是你之前说的
0赞
Quentin
7/24/2023
@codingStarter — 是的,方法只是属性(以函数作为其值),但 OP 在此处分配方法的方式并不能使其成为公共实例字段。
0赞
codingStarter
7/24/2023
@Quentin谢谢,我也查了一下 - 如果您使用 method = function(){},它将是一个实例字段,也许为了清楚起见而添加它
4赞
3limin4t0r
7/24/2023
#2
class Parent {
method = "sss";
}
本质上是以下方面的快捷方式:
class Parent {
constructor() {
this.method = "sss";
}
}
这意味着与以下方面存在一些重要区别:
class Parent {
method() {
console.log("Parent");
}
}
在变体中,将设置为创建的实例的自有属性()。
method = "sss"
method
new Child()
child.hasOwnProperty("method") //=> true
而定义普通方法不会设置为实例的自有属性。相反,它被设置在原型链上。
method() { console.log("Parent") }
Parent.prototype.hasOwnProperty("method") //=> true
构造函数代码仅在初始化实例时运行。这意味着在定义 and 类后(每当您使用 创建实例时)将始终运行。
this.method = "sss"
Parent
Child
new
class Parent {
prop = "parent value";
// aka
// constructor() {
// this.prop = "parent value";
// }
method() {
console.log("Parent");
}
}
class Child extends Parent {
prop() {
return "child Value";
}
method() {
console.log("Child");
}
}
const child = new Child();
const log = (jsString) => console.log(jsString, '//=>', eval(jsString));
log(`child.hasOwnProperty("prop")`);
log(`child.hasOwnProperty("method")`);
log(`Parent.prototype.hasOwnProperty("prop")`);
log(`Parent.prototype.hasOwnProperty("method")`);
最终的子实例结构如下所示:
new Child()
// returns
Child{ // Child instance depicted using object notation
// own properties
prop: "parent value", // set by the Parent constructor
// prototype chain depicted using the __proto__ (deprecated) property
__proto__: {
// Child.prototype
prop() { return "child Value" },
method() { console.log("Child") },
__proto__: {
// Parent.prototype
method() { console.log("Parent") },
}
}
}
有关更多详细信息,我建议通读 MDN 公共类字段页面。
评论
child.method
toString