简体   繁体   中英

Javascript OOP - inheritance and prototyping

I'm trying to use OOP in Javascript with inheritance and prototyping. Would you please have a look at my JSfiddel http://jsfiddle.net/Charissima/daaUK/ . The last value is the problem, thank you. I cannot understand why the function drive with raceCar doesn't get the totalDistance, which a set per putTotalDistance.

        function Car () {
            var that = this;

            this.totalDistance = 0;

            this.putTotalDistance = function(distance) {
                that.totalDistance = distance;
            };

            this.getTotalDistance = function() {
                return this.totalDistance;      
            };  

            this.drive = function(distance) {
                that.totalDistance += distance;     
                return that.totalDistance;
            };

            this.privateFunc = function() { 
                return 'car ' + this.totalDistance;
            };
        };


        function RaceCar (initialDistance) {
            var that = this;

            this.prototype = new Car();
            this.drive = function(distance) {
                return that.prototype.drive(2*distance);
            };

            this.privateFunc = function() {
                return 'raceCar ' + that.getTotalDistance();
            };
        };


        RaceCar.prototype = new Car();

        car = new Car;
        raceCar = new RaceCar;          


        car.putTotalDistance(200);
        alert('car totalDistance = ' + car.drive(10) + ' - ok');

        raceCar.putTotalDistance(200);
        alert('raceCar totalDistance before drive = ' + raceCar.getTotalDistance() + ' - ok');
        alert('raceCar totalDistance after drive = ' + raceCar.drive(10) + ' Why not 220?');                

Try this:

function Car () {    
    this.totalDistance = 0;
};

Car.prototype.putTotalDistance = function(distance) {
    this.totalDistance = distance;
};

Car.prototype.getTotalDistance = function() {
    return this.totalDistance;      
};  

Car.prototype.drive = function(distance) {
    this.totalDistance += distance;     
    return this.totalDistance;
};


function RaceCar () {};
RaceCar.prototype = new Car();
RaceCar.prototype.parent = Car.prototype;
RaceCar.prototype.drive = function(distance) {
    return this.parent.drive.call(this, (distance * 2));
};

raceCar = new RaceCar();
raceCar.putTotalDistance(200);

document.body.innerHTML = 'raceCar totalDistance after drive = ' + raceCar.drive(10);

EDIT:

As pointed out in one of the other answers, the main problem is setting the prototype inside the constructor . Instead, set it separately. In the code above, I linked the car prototype to a racecar prototype parent property and then fire the parent's drive function using call so that the context of the function is set to the racecar (via this ) and then passing the argument along.

Thank you, this works fine, but unfortunately another function I need is broken now. I created a new JSFiddle: http://jsfiddle.net/Charissima/5g6GV/

car.putTotalDistance(0);            
raceCar.putTotalDistance(100);
var drivingFunctions = [car.drive, raceCar.drive];

myText += drivingFunctions[0](10) + '<br>';
try {
    myText += drivingFunctions[1](100) + '<br>';                
}
catch(err) {
    myText += err + '<br>'
}

Firstly var that = this; is unnecessary. In a object context this will always refer to the instance.

You also don't want to set the objects prototype inside it's own constructor.

If you want to access the prototype of a class don't try to access it through the instance.

The update fiddle

function RaceCar (initialDistance) {
    //var that = this;
    //this.prototype = new Car();

    this.drive = function(distance) {
        return RaceCar.prototype.drive(2*distance);
    };          
};

// This correctly sets the prototype
RaceCar.prototype = new Car();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM