0

I have this Car function:

var Car = function(vendor, model, year) {
    return {
        vendor: vendor,
        model: model,
        year: year,
        name: (function() {
            return vendor + " " + model + " " + year;
        })()
    };
};
var foo = Car("Toyota","Corola",2007);
alert(foo.name);  //alerts "Toyota Corola 2007"

This works, but I want the name to be able to change according to the vendor, model, and year.

taxi.vendor = "Mitsubishi";
alert(taxi.vendor); //still alerts "Toyota Corola 2007"

How can I instead make it alert Mitsubishi Corola 2007 according to the change of the vendor property?

EDIT: And the catch -- name must remain a property that does not need to be called as a function.

1

3 Answers 3

4

With recent versions of WebKit (Safari, Chrome) or Firefox, you can define getter and setter functions:

var o = {a: 7, get b() {return this.a + 1;}, set c(x) {this.a = x / 2}};
o.b // result is 8
o.a = 10
o.b // result is 11

Then you would do this:

var Car = function(vendor, model, year) {
    return {
        vendor: vendor,
        model: model,
        year: year,
        get name() { return this.vendor + " " + this.model + " " + this.year; }
    };
};

And get the result that you want.

I don't know if IE or Opera support this or which versions. If you need to support anything other than recent Safari, Chrome, or Firefox browsers then you're better off using a function to access the name instead of leaving it as a property:

var Car = function(vendor, model, year) {
    return {
        vendor: vendor,
        model: model,
        year: year,
        name: function() { return this.vendor + " " + this.model + " " + this.year; }
    };
};

And then:

var foo = Car("Toyota","Corola",2007);
alert(foo.name());  //alerts "Toyota Corola 2007"
foo.vendor = "Mitsubishi";
alert(foo.name());  //alerts "Mitsubishi Corola 2007"
Sign up to request clarification or add additional context in comments.

Comments

2

When you use name: (function() {return vendor + " " + model + " " + year;})(), that means that the name property will be set to the result of executing this function. This happens when you create a new Car. But it sounds like you want this to update dynamically, so consider having name be a getter function instead of just a string property:

name: function() {return vendor + " " + model + " " + year;}

Then you can do alert(taxi.name()), which will dynamically concatenate the vendor, model, and year strings.

2 Comments

Is it possible without making name a function?
If you want to do it without making name a function, you would have to make setter functions (e.g. setVendor, setModel, and setYear) so that each time something changes you could recreate the name. You can also use getters and setters as another commenter mentioned.
2

How about:

 var Car = function(thevendor, themodel, theyear) {
    this.vendor = thevendor;
    this.model = themodel,
    this.year = theyear,
    this.name = function() {
            return this.vendor + " " + this.model + " " + this.year;
        };
    return this;
};


var foo = new Car("Toyota","Corola",2007);
alert(foo.name());  //alerts "Toyota Corola 2007"

foo.vendor = "Mitubishi";
alert(foo.name());  //alerts "Mistubishi Corola 2007"

JSFiddle for this code: http://jsfiddle.net/duncan_m/gZKQD/

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.