guest
guest

Reputation: 2224

javascript object - why undefined properties?

Why does this code produce an undefined for setMedium and setLarge? I would like these to look like similar methods to setSmall. What do I have to do to correctly define these as methods?

function Box() {
    this.length = 14;
    this.width = 10;
    this.height = 6;
    this.setSmall = function (){
        this.length = 14;
        this.width = 10;
        this.height = 6;
    }
    this.setMedium = setBoxDimensions(16,14,6);
    this.setLarge = setBoxDimensions(24,14,6);
    this.initBoxDimensions = this.setSmall;

    function setBoxDimensions(length, width, height){
        this.length = length;
        this.width = width;
        this.height = height;
    }
}
var newBox = new Box();
newBox.setSmall();
console.log(newBox);

Upvotes: 1

Views: 53

Answers (4)

user1106925
user1106925

Reputation:

First, you need to assign a function to an object. Right now you're invoking a function, not assigning it.

If you want to invoke setBoxDimensions with static arguments, then you assign an anonymous function to this.setMedium/Large and have that invoke setBoxDimensions.

But it also seems that you don't want setBoxDimensions to be exposed. In that case, you need to invoke it via the .call() method, which lets you set its this value.

function Box() {

    // use the setBoxDimensions since we have it.
    this.setSmall = function (){
        setBoxDimensions.call(this, 14,10,6);
    }

    this.setSmall(); // to initialize instead of repeating the code above

    // assign anonymous functions that invoke `setBoxDimensions`
    this.setMedium = function() {
        // call setBoxDimensions, and set its `this` to the current `this`
        setBoxDimensions.call(this, 16,14,6); 
    }
    this.setLarge = function() {
        // call setBoxDimensions, and set its `this` to the current `this`
        setBoxDimensions.call(this, 24,14,6);
    }

    this.initBoxDimensions = this.setSmall;

    function setBoxDimensions(length, width, height){
        this.length = length;
        this.width = width;
        this.height = height;
    }
}
var newBox = new Box();
newBox.setSmall();
console.log(newBox);

If you wanted setBoxDimensions to be a publicly exposed method, then you can set it on this. Also, it's probably a good idea to take advantage of prototypal inheritance here.:

function Box() {
    this.setSmall();
}

Box.prototype.setSmall = function (){
    this.setBoxDimensions(14,10,6);
}
Box.prototype.setMedium = function() {
    this.setBoxDimensions(16,14,6); 
}
Box.prototype.setLarge = function() {
    this.setBoxDimensions(24,14,6);
}

Box.prototype.initBoxDimensions = Box.prototype.setSmall;

Box.prototype.setBoxDimensions = function(length, width, height){
    this.length = length;
    this.width = width;
    this.height = height;
}

var newBox = new Box();
newBox.setSmall();
console.log(newBox);

Upvotes: 2

plalx
plalx

Reputation: 43718

I think that what you are trying to achieve is called partial function application, which is basically creating a derived function from an exisiting one, but that will be called with predefined parameters.

this.setMedium = setBoxDimensions.bind(this, 16,14,6);
this.setLarge = setBoxDimensions.bind(this, 24,14,6);

Upvotes: 1

Pointy
Pointy

Reputation: 413682

Your initialization statements like this:

this.setMedium = setBoxDimensions(16,14,6);

are calling the function "setBoxDimensions". If you want "setMedium" to be a call to "setBoxDimensions" with particular arguments, you need to make it be a function to do that:

this.setMedium = function() {
    this.setBoxDimensions(16,14,6);
}.bind(this);

Whenever you mention a function and follow that by a parenthesized list of arguments, you're making a function call then and there.

The .bind() function used above arranges for this to be correctly set in the anonymous wrapper function. An alternative that will work in really old browsers is:

var that = this;
this.setMedium = function() {
    that.setBoxDimensions(16, 14, 6);
};

Upvotes: 3

Gabriel
Gabriel

Reputation: 18780

because setBoxDimensions does not return a value. Also the context of setBoxDimension is the global object.

Upvotes: 1

Related Questions