Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在JavaScript中修改super.method()失败?_Javascript_Ecmascript 6_Es6 Class - Fatal编程技术网

为什么在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
    没有更新父类中引用的方法
  • 为什么JavaScript在修改
    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)).