Javascript OOP - inheritance and prototyping

2019-09-14 03:06发布

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?');                

3条回答
虎瘦雄心在
2楼-- · 2019-09-14 03:20

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();
查看更多
来,给爷笑一个
3楼-- · 2019-09-14 03:42

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>'
}
查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-09-14 03:44

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.

查看更多
登录 后发表回答