set attribute with javascript super method [duplicate]

断了今生、忘了曾经 提交于 2019-11-28 12:32:22

ECar.prototype = new Car();

At this line ECar's prototype get a context, in which all ECar's instance will be shared.

ECar.prototype.setT.call(this, p);

This line will call at that context, not what has been created while calling super at Car.call(this, id);.

You can fix your code with

function ECar(id) {  
  Car.call(this, id);  // super constructor call
  var carSetT = this.setT;
  this.setT = function(p) {
    carSetT.call(this, p);
  }
}

but it would be better (and more readable) to use real prototypes, such as

function Car() {}

Car.prototype.getT = function () { /* ... */ };
Car.prototype.setT = function () { /* ... */ };

function ECar() {}

ECar.prototype = new Car();
ECar.prototype.setT = function () { /* ... */ };

Edit: note (as @Bergi suggested)

You should only use Child.prototype = new Parent() as inheritance if you must support legacy browsers & then you should only use empty constructors.

The most (other-language) compatible way in JavaScript for inheritance is

Child.prototype = Object.create(Parent.prototype)

(MDN says it is supprted from IE 9)

Bergi

// attribute t isn't changed ..

Please notice that t is not an "attribute", but a variable local to the constructors scope ("private").

ECar.prototype.setT.call(this, p); // super call

does not work how you expect it. You seem to want to change the variable created with the call to your super constructor (it's still local to that variable environment, and exposed by the getT and setT functions that were created in the constructor. So now, you are calling the function that was created in the line ECar.prototype = new Car(); - which changes the variable t that was created there. That you call the function on the current object does not matter, as it does not use the this keyword inside.

So, you don't want to a) use the method of that prototype Car, but your own and b) don't want to create an instance of Car for the prototype at all. See also What is the reason [not] to use the 'new' keyword here?. To apply the super constructor on your current instance is enough. If you want to extend the methods while still using the old ones, you need to preserve them (and exactly them) in a variable.

function Car(id) {
    var t = "default";
    this.getT = function () {
        return t;
    };
    this.setT = function (p) {
        t = p;
    };
}

function ECar(id) {
    Car.call(this, id); // super constructor call

    var oldSetter = this.setT;
    this.setT = function (p) { // override
        oldSetter(p); // call the function which access this instance's "t"
    }
}
ECar.prototype = Object.create(Car.prototype, {constructor: {value: ECar}});

var ecar = new ECar(3);
ecar.setT(4);
console.log(ecar.getT()); // prints 4
function Car(i) {
   var id = i;
   var t = "default";

   this.getT = function() { return t; }
   this.setT = function(p) {
      t = p;  // attribute t isn't changed ..
   }
}

 function ECar(id) {  
     Car.call(this, id);  // super constructor call
 }

ECar.prototype = new Car();
ECar.prototype.constructor = ECar;  //Never forget doing this
ecar = new ECar(3);
ecar.setT(4);
alert(ecar.getT());

You don't need to override setT function. ​

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!