2

I'm having some trouble with thh following code:

var num_passengers;


function vehicleConstructor(name, num_wheels, num_passengers)
{
    var vehicle = {};
    vehicle.name = name;
    vehicle.num_wheels = num_wheels;
    vehicle.num_passengers = num_passengers;

    vehicle.makenoise = function() {

    }
    return vehicle;
}

var bus = vehicleConstructor("bus", 5, 10);

bus.pickUpPassengers = function(toPickUp){
    num_passengers += toPickUp;
    return num_passengers;
} 


 bus.pickUpPassengers(5);

I’ve added a global num_passengers for the pickUpPassengers() to avoid it being undefined.

However, I’m still receiving a NAN for the pickUpPassegers method of the bus instance.

Is it a matter of scoping or definition?

4
  • this should help stackoverflow.com/a/13522017 Commented Jun 8, 2016 at 16:33
  • num_passengers is never initialized with a value. What you are referencing inside pickUpPassengers is the global variable you defined at the top, not the vehicle instance property you added to the object in vehicleConstructor. Commented Jun 8, 2016 at 16:34
  • num_passengers is undefined. Commented Jun 8, 2016 at 16:34
  • 1
    inside bus.pickUpPassengers() this.num_passengers is the value bound to the bus instance if thats what your looking for ... (i.e would return 15) Commented Jun 8, 2016 at 16:35

3 Answers 3

1

Just one small problem on finding the current instance. You simply need to define which instance you need for num_passengers with 'this'.

Also, This way you do not need the global variable for num_passengers, which means you can have multiple instances( car, bus, and motorcycle) at the same time. This will potentially avoid future problems.

function vehicleConstructor(name, num_wheels, num_passengers)
{
    var vehicle = {};
    vehicle.name = name;
    vehicle.num_wheels = num_wheels;
    vehicle.num_passengers = num_passengers;

    vehicle.makenoise = function() {

    }
    return vehicle;
}

var bus = vehicleConstructor("car", 5, 10);

bus.pickUpPassengers = function(toPickUp){
    this.num_passengers += toPickUp;
    return this.num_passengers;
} 
Sign up to request clarification or add additional context in comments.

2 Comments

I would get rid of that confusing initial & unneeded var num_passengers;
Thanks @AlexK. Good call on that fix.
1

It is a matter of num_passengers definition. You should init it as a number at the beginning:

var num_passengers = 0;

But if you want to change value of num_passengers of your bus Object, you should use this and throw out first definition of num_passengers:

bus.pickUpPassengers = function(toPickUp){
    this.num_passengers += toPickUp;
    return this.num_passengers;
}

1 Comment

This would be true if the intention is for all instances of a vehicle to share a single cumulative value, I don't think thats the case.
1

Here is how I would write your code:

function Vehicle (name, options) {
  this.name = name
  this.wheels = options.wheels
  this.passengers = options.passengers
}

Vehicle.prototype.makeNoise = function () {
  console.log('vroom')
  return this
}

var bus = new Vehicle('bus', { wheels: 4, passengers: 10 })

bus.pickUpPassengers = function (toPickUp) {
  this.passengers += toPickUp
  return this
}

bus.pickUpPassengers(5)

This uses JavaScript's prototypical inheritance, which can be used like classes in other languages. Constructors start with a capital letter (by convention) and are called with new. Using prototypes also means that you don't define methods like makeNoise every time you create a new vehicle, instead all the vehicles refer back to the prototype.

I've also used return this at the end of the methods as it allows chaining:

// Without chaining:
foo.bar()
foo.baz()
foo.qux()

// With chaining:
foo.bar().baz().qux()

The Vehicle constructor also takes the numbers of wheels and passengers in an options object, which makes it easier to read and understand what the numbers are for.


With ES6 it would look like this:

class Vehicle {
  constructor (name, { wheels, passengers } = {}) {
    this.name = name
    this.wheels = options.wheels
    this.passengers = options.passengers
  }
  makeNoise () {
    console.log('vroom')
    return this
  }
}

class Bus extends Vehicle {
  constructor (options) {
    super('bus', options)
  }
  pickUpPassengers (toPickUp) {
    this.passengers += toPickUp
    return this
  }
}

const bus = new Bus({ wheels: 4, passengers: 10 })
bus.pickUpPassengers(10)

(Here I chose to make Bus a subclass of Vehicle because it's easier with ES6. It also helps you if you want to create more than one bus.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.