为什么在JavaScript中修改super.method()失败?
我试图通过将父类的方法作为为什么在JavaScript中修改super.method()失败?,javascript,ecmascript-6,es6-class,Javascript,Ecmascript 6,Es6 Class,我试图通过将父类的方法作为super的属性进行访问来修改它。我有两个问题: 为什么修改super.getTaskCount没有更新父类中引用的方法 为什么JavaScript在修改super.getTaskCount时没有给出任何错误?代码执行过程中到底发生了什么 让我们来看一个例子: //父类 班级项目{ getTaskCount(){ 返回50; } } //儿童班 类SoftwareProject扩展项目{ getTaskCount(){ //让我们尝试修改父类的“getTaskCoun
super
的属性进行访问来修改它。我有两个问题:
super.getTaskCount
没有更新父类中引用的方法李>
super.getTaskCount
时没有给出任何错误?代码执行过程中到底发生了什么//父类
班级项目{
getTaskCount(){
返回50;
}
}
//儿童班
类SoftwareProject扩展项目{
getTaskCount(){
//让我们尝试修改父类的“getTaskCount”方法
super.getTaskCount=函数(){
返回90;
};
返回super.getTaskCount()+6;
}
}
设p=newsoftwareproject();
console.log(p.getTaskCount());//印刷品56。为什么不呢?
//为什么super.getTaskCount方法保持不变?
重写super方法不是一个好的设计,但如果您真的想更改,可以这样做
类项目{
getTaskCount(){
返回50;
}
}
//儿童班
类SoftwareProject扩展项目{
getTaskCount(){
//让我们尝试修改父类的“getTaskCount”方法
让getTaskCount=Project.prototype;
Project.prototype.getTaskCount=函数(){
返回90;
};
让count=super.getTaskCount()+6;
Project.prototype.getTaskCount=getTaskCount;
返回计数;
}
}
设p=newsoftwareproject();
log(p.getTaskCount())代码>表面上看,super
看起来很像这个
。但这是一个很大的不同,细节并不完全直观。关于其真实性质的第一个提示是,关键字super
自身浮动在语法上是无效的
console.log(此);//作品`这个`指的是一个值
console.log(超级);//抛出一个语法错误
相反,超级调用-super()
-是某些构造函数中可用的特殊语法,而超级属性-super.foo
或super[foo]
-是方法中可用的特殊语法。在这两种情况下,表达式都不能进一步简化为独立于其右侧的super
部分
在我们了解超级属性是赋值的左侧时会发生什么之前,我们需要了解评估超级属性本身的实际作用
在中,前两种情况与超性能生产相对应,并且非常相似。您将看到,这两种情况下的算法都是从检索当前this
值开始,然后继续执行操作结束的,我们将在下面介绍
(我将省略一些步骤的作用,因为如果我们走遍所有内容,我们会整天都在这里;相反,我想提醒大家注意与您的问题相关的有趣部分。)
在MakeSuperPropertyReference中,第三步是使用env.GetSuperBase()
检索“baseValue”。此处的“env”是指最近的环境记录
它有自己的“this”绑定。环境记录是一个规范概念,它对闭包或范围进行建模——这不是完全相同的事情,但现在已经足够接近了
在env.中,有对环境记录的[[HomeObject]]
的引用。此处的双括号表示与等级库模型关联存储的数据。环境记录的HomeObject与被调用的相应函数的[[HomeObject]]相同(如果存在的话)(它不会在全局范围内)
什么是函数的同胚对象?当以语法方式创建方法时(在对象文本或类主体中使用foo(){}
语法),该方法与创建它的对象“相关联”,即它的“主对象”。对于类主体中的方法,这意味着普通方法的原型和静态方法的构造函数。与通常完全“可移植”的不同,方法的同源对象永久固定为特定值
同源对象本身不是“超级对象”。相反,它是对从中派生“超级对象”(基础)的对象的固定引用。实际的“超级对象”(super object)或base是HomeObject的当前[[原型]]的任何对象。因此,即使[[HomeObject]]是静态的,super
所指的对象也可能不是:
class Foo{qux(){return 0;}
类Baz{qux(){return 1;}}
类栏扩展了Foo{qux(){return super.qux();}
log(新的Bar().qux());
// 0
log(Bar.prototype.qux.call({}));
//也是0![[HomeObject]]仍然是Bar.prototype
//然而。。。
Object.setPrototypeOf(Bar.prototype,Baz.prototype);
log(新的Bar().qux());
//1-Bar.prototype[[prototype]]已更改,因此GetSuperBase解析了不同的基
因此,现在我们对“super.getTaskCount”中的“super”有了一些额外的了解,但仍然不清楚为什么分配给它会失败。如果我们现在回头看一下MakeSuperPropertyReference
,我们将从最后一步得到下一条线索:
“返回一个Reference类型的值,该值是其基值为
组件为bv[ed.基本值],其引用名称为组件
propertyKey,其thisValue组件为actualThis[ed.当前this
],
并且其严格引用标志是严格的。”
这里有两件有趣的事情。一种是“超级参照”是一种特殊的参照,另一种是“超级参照”。。。“引用”可以是一种返回类型!JavaScript没有具体化的“引用”,只有值,那么给出了什么呢
引用确实作为规范conc存在
b. Let succeeded be ? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).