0

I'm writing some JavaScript with three classes, one for Roofs, one for Garages, and one for Houses. The house class takes two arguments to its constructor, a Roof and a Garage. When I run this code I get:

can not construct object [Break on this error] throw new Error('can not construct object');\n

in Firebug even though the objects are clearly of the right type. Any idea what I'm doing wrong? Here's the code:

function Roof(type, material) {
     this.getType = function() { return type; }
     this.getMaterial = function() { return material; }
}

function Garage(numberOfCars) {
     this.getNumberOfCars = function() { return numberOfCars; }
}

function House(roof, garage) {
     if (typeof roof !== 'Roof' || typeof garage !== 'Garage') {
          throw new Error('can not construct object');
     }

     this.getRoof = function() { return roof; }
     this.getGarage = function() { return garage; }
}

myRoof = new Roof("cross gabled", "wood");
myGarage = new Garage(3);
myHouse = new House(myRoof, myGarage);
alert(myHouse.getRoof().getType());
0

3 Answers 3

1

The typeof operator will return "object" for your objects, not their names. See the typeof Operator documentation.

function House(roof, garage) {
    alert(typeof roof);   // "object"
    ...

You probably want instanceof:

function House(roof, garage) {
    if (!(roof instanceof Roof) || !(garage instanceof Garage)) {
    ...
Sign up to request clarification or add additional context in comments.

1 Comment

You're right! So how would one go about making sure the right kind of object was passed into the constructor? I wouldn't want somebody passing in a Foo object when I was expecting a Roof...
1

myRoof and myGarage are object types.

If you want to check if myRoof is an instance of Roof, use isinstanceof.

>>myRoof isinstanceof Roof
True

Comments

1

As noted by Richie, typeof will return 'object', not the name of the function. You should use the 'constructor' property. Use 'instanceof' operator.

Also, I have used two 'if statements' (instead of one, like you did) to throw different error message based on the particular error. This may mean a little more code, but when the code breaks, you know exactly what went wrong.

Working demo →

Code:

function Roof(type, material) {
     this.getType = function() { return type; }
     this.getMaterial = function() { return material; }
}

function Garage(numberOfCars) {
     this.getNumberOfCars = function() { return numberOfCars; }
}

function House(roof, garage) {
     if (roof instanceof Roof)
     {
        throw new Error('Argument roof is not of type Roof');
     }

     if(garage instanceof Garage) 
     {
          throw new Error('Argument garage must be of type Garage.');
     }

     this.getRoof = function() { return roof; }
     this.getGarage = function() { return garage; }
}

myRoof = new Roof("cross gabled", "wood");
myGarage = new Garage(3);
myHouse = new House(myRoof, myGarage);
alert(myHouse.getRoof().getType());

4 Comments

Bobice, you are right, it's better to use instanceof. Corrected the answer. I should not rush to answer a question! :)
Don't use constructor. It's not standard, not available in IE, and it doesn't do what you think as soon as you start using prototypes. The only standard, reliable way to test the inheritance of an object in JavaScript is instanceof.
oops, temporal anomaly! (ahem)

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.