问题描述在看阮一峰大神的ECMAScript6入门中有关继承的部分的时候,有一个问题:前面提到super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类那么下面的代码classA{constructor(){this.x=1;}}classBextendsA{constructor(){super();this.x=2;super.x=3;console.log(super.x);//undefinedconsole.log(this.x);//3}}letb=newB();当设置super.x=3时,我的理解相当于是A.prototype.x=3但实际上好像这里的super就像this一样,虽然文中提到ES6规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例,但我认为这里的super不是在调用父类的方法结果希望大神能帮我解释一下这里super怎么回事,万分感激
2 回答
忽然笑
TA贡献1806条经验 获得超5个赞
super.x=3;这个赋值有点特殊。super是A.prototype。对它的读取来自A.prototype。但是,对它的赋值会进入this里。这是向super.x赋值特殊的地方。读取的时候:console.log(super.x),会从A.prototype里读,里面没有x,于是输出undefined。==================以下写给想看一眼标准的:val.x的形式会生成一个Reference,记录了它是哪来的(base,这里是val),它叫什么(referencedname,这里是"x"),以及其它。但是super.x会额外记录一个信息,就是当前的this(thisValue)。super.x的base是父类的prototype。赋值的时候,会使用PutValue(V,W),其实V就是刚刚提到的super.x生成的Reference,W是要被赋进去的值。然后它会执行:base.[[Set]](GetReferencedName(V),W,GetThisValue(V)).GetReferencedName(V)与GetThisValue(V)分别取出了Refrence里记录的refrencedname("x"),与thisValue(保存的this)。它是给base的"x"属性赋值W。但是多了一个thisValue是干嘛的呢...我们来看真正执行赋值的地方:OrdinarySetWithOwnDescriptor(O,P,V,Receiver,ownDesc)这里O是上面的base(父类的prototype),P是属性名("x"),V的要赋的值,Receiver就是thisValue这个算法略长,拿出其中一步(这一步也不短...):3.IfIsDataDescriptor(ownDesc)istrue,thena.IfownDesc.[[Writable]]isfalse,returnfalse.b.IfType(Receiver)isnotObject,returnfalse.c.LetexistingDescriptorbe?Receiver.[[GetOwnProperty]](P).d.IfexistingDescriptorisnotundefined,theni.IfIsAccessorDescriptor(existingDescriptor)istrue,returnfalse.ii.IfexistingDescriptor.[[Writable]]isfalse,returnfalse.iii.LetvalueDescbethePropertyDescriptor{[[Value]]:V}.iv.Return?Receiver.[[DefineOwnProperty]](P,valueDesc).e.ElseReceiverdoesnotcurrentlyhaveapropertyP,i.Return?CreateDataProperty(Receiver,P,V).可以看到,所有的值,其实都写进了Receiver,也就被保存的this。注:对普通的val.x,Reference没有thisValue,GetThisValue直接返回base。这样OrdinarySetWithOwnDescriptor中O与Receiver是同一个对象。注2:读的时候,如果不是getter,直接返回base里的属性值。注3:super.func()里的this,用的thisValue。val.func()的this,用的base(也就是val)
三国纷争
TA贡献1804条经验 获得超7个赞
super()其实是相当于newA()只执行constructor产生的this用来构建B实例super关键字===A.prototype你可以这样理解super与super()时的super不是一个东西
添加回答
举报
0/150
提交
取消