0

I've got a little factory pattern example I'm playing with that works fine and gives me a way to create related objects with a generic interface:

 $(document).ready(function () {
            function Car(options) {
                this.color = options.color || 'unknown',
                this.name = options.carName || 'unknown',
                this.doors = options.doors || 4;
            }
            function Truck(options) {
                this.color = options.color || 'unknown',
                this.name = options.name || 'unknow',
                this.doors = options.doors || 2;
            }
            function VehicleFactory() { };
            VehicleFactory.prototype.createVehicle = function (options) {
                if (options.vehicleType === 'car') {
                    return new Car(options);
                }
                else {
                    return new Truck(options);
                }
            }
            var factory = new VehicleFactory();
            var car = factory.createVehicle({
                vehicleType: 'car',
                name: 'bill',
                doors: 2
            });
            console.log(car instanceof Car);//true
            var truck = factory.createVehicle({
                vehicleType: 'truck',
                doors: 3

            });
            //checks to make sure that objects are of the right type
            console.log('truck is an instance of Car: ' + (truck instanceof Car)); //false
            console.log('truck is an instace of Truck: ' + (truck instanceof Truck)); //true
            console.log(truck);
        });

Coming from C# this looks familiar enough and it easy for me to grok. However, I also tend to try to stand on the shoulders of giants and Doug Crockford said no to new.
How could I refactor this code to use Object.create instead of new. Does it REALLY matter to the average person, or does it only matter because the upper echelon says it does?

4
  • 1
    Maybe a link to Crockford's comments would help us interpret them in context. Commented Oct 24, 2013 at 18:48
  • @MikeSamuel this was in a three-part series he did with each video being about an hour long, I'll try to see if I can find a more prudent resource. Commented Oct 24, 2013 at 18:49
  • 1
    it wasn't a total avoidance of the new keyword. Object.create allows for inheritance in JS (ECMA 5). Using new to create a parent object only allows a reference to that object within the class, it doesn't inherit from it per-se. Commented Oct 24, 2013 at 18:51
  • Related question: stackoverflow.com/questions/383402/… Commented Oct 24, 2013 at 18:51

1 Answer 1

2

How could I refactor this code to use Object.create instead of new?

return new Car(options);

is equivalent (for non-host constructors, and modulo non-object returns) to

var newCar = Object.create(Car.prototype);
return Car.call(newCar, options) || newCar;

which creates an object, and then invokes Car to initialize it.

You could further refactor Car to take an unfinished car to initialize instead of modifying this:

function initializeCar(car, options) {
  car.color = options.color || "red";
  ...
  return car;
}

and then your object creation and initialization code would be

return initializeCar(Object.create(protoCar), options);

but I don't know if any of this is addressing Crockford's main concerns.


Finally putting createVehicle on VehicleFactory.prototype doesn't seem to get you anything. Why

VehicleFactory.prototype.createVehicle = ...

?

Sign up to request clarification or add additional context in comments.

7 Comments

And allows Car to inherit the prototype and namespace of the original class... good answer.
@Mike could you tell me why that why I refactor out my return new Car(options) to your return.Car.call... that the line ` console.log('Car is instance of car: ' + (car instanceof Car)); //old way fired true, not it's false ` is now false?
Unless you're using an implementation of Object.create that is non-standard, it should work the same w.r.t instanceof.
wrt? this seems like some jargon I need to know :)
@MikeSamuel I forgot that you could pass arguments to Object.create, good answer.
|

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.