Syntax problems? Writing constructor function

I’m trying to add a method to a class like this:

function Ship(draft,crew) {
 this.draft = draft;
 this.crew = crew;
 this.isWorthIt = function (draft, crew) {
   return draft - crew * 1.5 > 20;
 }
}

This is a merchant ship that my pirate crew wants to loot. The .isWorthIt method determines if there is enough booty on the ship by subtracting the weight of its sighted crew from entire weight (guessed from keel depth :smile:).
My problem is, the method returns false when I think if should return true (ship has enough booty for looting).

let worthyShip = new Ship(100, 20);

console.log(worthyShip); //Ship { draft: 100, crew: 20, isWorthIt: [Function (anonymous)] }
let wShipWeightOfCrew = worthyShip.crew * 1.5;
console.log(wShipWeightOfCrew); //30
let wShipWeightWithoutCrew = worthyShip.draft - wShipWeightOfCrew;
console.log(wShipWeightWithoutCrew); //70
console.log(wShipWeightWithoutCrew > 20); //true

But:
console.log(worthyShip.isWorthIt()); //false

A function with the exact same syntax but no variables returns true:

function returnTrue () {
  return 100 - 20 * 1.5 > 20;
}
console.log(returnTrue()); //true
  • Question 1:
    Why does worthyShip.isWorthIt() return false?

  • Question 2:
    If I write the constructor like this:

function Ship(draft,crew) {
 this.draft = draft;
 this.crew = crew;
 this.isWorthIt = function (this.draft, this.crew) { //object properties with this.
return this.draft - this.crew * 1.5 > 20;
 }
}

The interpreter throws an error “SyntaxError: Unexpected token ‘this’”. I have seen a few similar examples where ‘this.’ was used in defining methods in the constructor, but here, this. is not wanted. Why is that?

We would not write a function with fixed values in the parameters. They are supposed to be local variables, or in the case of this method, would have no parameters.

isWorthIt is a method, so would not be written in context.

isWorthIt () {
    return (this.draft - this.crew) * 1.5 > 20
}
1 Like

I don’t understand. What do you mean by this?

You had a slight mixup in your function referencing your Ship object values, I posted a snippet below that might help to visualize it:

function Ship(draft, crew) {
  this.draft = draft;
  this.crew = crew;
  this.isWorthIt = function(draft, crew) {
    console.log(draft);
    console.log(crew);
    console.log(this.draft);
    console.log(this.crew);
    return this.draft - this.crew * 1.5 > 20;
  }
}

let worthyShip = new Ship(100, 20);

console.log(worthyShip.isWorthIt());
  1. The parameters are simply placeholder value identities, so you shouldn’t be using this as part of a parameter since this is used to access an object’s value which wouldn’t be our goal for a parameter. Your original code was correct with not using this in your parameter.
  2. The reason the logic error is occurring is because your method is using draft and crew for its calculation, this would normally be fine outside of an object, but you want to use the Ship object’s values to do the calculations. If you run the snippet above and output draft and crew, you will see they are actually undefined, which is because they are new variables being created at the time you reference them as a result of JavaScript’s loosely-typed nature. To get the values you actually want in your calculation, you should reference the object’s values for them, such as: this.draft and this.crew, which the logs from the previous snippet would output the expected values.
  3. After experimenting with this, you’ll notice you don’t even need parameters at all for the function since it is a method of the object and we are directly using the object’s values for the calculation, so your final working code would look like:
function Ship(draft, crew) {
  this.draft = draft;
  this.crew = crew;
  this.isWorthIt = function() {
    return this.draft - this.crew * 1.5 > 20;
  }
}

It’s been ages since I worked with constructor functions given that JS now has classes. Belay that comment.

Consider this, instead:

function Ship(draft,crew) {
 this.draft = draft;
 this.crew = crew;
 this.isWorthIt = function () {
   return (this.draft - this.crew) * 1.5 > 20;
 }
}

Note there are no parameters on the method.

The math is unclear since we do not know what precedence applies.


Here is an example of the JS class:

class Ship {
    constructor(draft, crew) {
        this.draft = draft;
        this.crew = crew;
    }
    isWorthIt () {
        return (this.draft - this.crew) * 1.5 > 20
    }
}

We use the new operator the same as with the old constructor functions.

bounty = new Ship (100, 20)
bounty.isWorthIt()    //  true

Please do clarify what the math should be. I’m a little confused how a ship would have a draft of 100’ and a crew of only 20. One would expect a 20 foot draft and 100 crew members.


context is execution context, namely the instance. this is the context variable that is bound to the instance that calls its methods, as well as the instance while it is being created.