1

When im working with javaScript plugins I often come across this approach for adjusting a plugins behaviour.

$('.mySlider').slider({status: "burnt"});

If I try and replicate this kind of approach with an object like so

var Egg = function(){

    this.details = {
        status: "cooked",
        make: "Happy Egg"
    }

};



var egg = new Egg({status: "burnt"});
console.log(egg.details.status);

I just get a bunch of undefined messages from the console. can anyone show me how to create an object and then change its properties like the above example?

Thanks

1
  • 3
    this code can't possibly work because the argument you pass to the constructor is just being ignored Commented Jul 31, 2012 at 17:16

6 Answers 6

6

Your constructor is not taking any arguments, yet you are passing them in when you create a new instance.

you would want

var Egg = function(props){

    this.details = props;

};

or perhaps

var Egg = function(props){
    props = props || {}; // handle no arguments

    this.status = props.status;
    this.make = props.make || "Happy Egg";
};

and then you would do just egg.status to get the property.

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

4 Comments

The line this.make: props.make || "Happy Egg"; looks like you mixed up JavaScript assignment and JSON formatting. ?
i would say my approach ( see below ) is allot more dynamic and is more commonly used
I prefer not to use jquery for everything. If your only tool is hammer, every problem is a nail.
Perfect! thanks, so its just creating a constructor that takes an object literal as an argument.
1

try this:

var Egg = function(details) {
   this.details = {};
   for (var key in details) {
      this.details[key] = details[key];
   }

   return this;
};

var egg = new Egg({ status: 'burnt' }); // burnt

console.log(egg.details.status);

The problem is that you were passing an argument (the details) to a constructor, but not using them properly. In my example I default the details to an empty object {} and then override any passed attributes on it.

You can take it one step further by using prototypes. Let's say you want to expose a function that lets you change a detail.

var Egg = function(details) {
   this.details = {};
   for (var key in details) {
      this.details[key] = details[key];
   }

   return this;
};

Egg.prototype.updateDetail = function(name, value) {
    this.details[name] = value;
};

var egg = new Egg({ status: 'burnt' });

console.log(egg.details.status); // burnt

egg.updateDetail('status', 'scrambled');

console.log(egg.details.status); // scrambled

Comments

0

you can create default parameters like this ( using jQquery )

var Egg = function(props){
    this.options= {
        status: "cooked",
        make: "Happy Egg"
    }
    $.extend(this.options, props);
};

Comments

0

For your simple Egg object, you would need your function to accept a parameter which is used to set the attributes of the resulting object:

var Egg = function(options) {
  this.details = {
    status: options.status || 'cooked',
    make: options.make || 'Happy egg'
  }
};

Of course, this is an extremely simplified version. Ideally, you would want to use an extend function, such as those provided by jQuery or underscore.

Comments

0

I have made an example where I construct an object then override its value by passing parameter to constructor as in the slider object. The example is not exactly as yours but more of the slider example you asked about

var Egg = function(){
this.status = 'Some';
    this.detail = 'another';
   //the magic line which makes it possible
    for (var n in arguments[0]) { this[n] = arguments[0][n];}

};

var egg = new Egg({status: 'burnt', make: 'hj'});
alert(egg.status );

By adding this line

for (var n in arguments[0]) { this[n] = arguments[0][n];}

to your constructor, you have given the user the flexibility to change any of the default parameters. They can specify the parameters in any order or leave out the one whic are not required.

Here is JSFiddle example

Comments

0

You have to put some code into your function that assigns the argument values to the new object's properties. Also, if you have some default values you should put them into the prototype, it saves memory. So use this code:

function Egg(obj){
  if(typeof obj==="object"){
    this.details={}; //This overwrites the prototype property with one
                     //that's specific to this instance.
    for(i in arguments.callee.prototype.details){
      //This copies object from proto to object
      this.details[i]=arguments.callee.prototype.details[i];
    }
    for(i in object){
      this.details[i]=object[i];
    }
  }
};
Egg.prototype={
    details: {status: "cooked", make: "Happy Egg"}
}

This code lets you have some default object that can be expanded/overwritten by an argument.

4 Comments

But this would change the property in every instance created, wouldn't it?
No, it wouldn't. The constructor only acts on this, which is the instance being created. The Egg.prototype={...} part just defines the prototype of the Egg class.
Hm, am I missing something? When I instanciate an Egg and set a status via constructor, then change the staus via prototype, the status parameter of my instantiated object also changes. jsfiddle.net/UPwUq
Yes, of course. If you change something in the prototype, it immediately changes that in all instances the didn't overwrite that property. So if you want to change something, do the changes to the object, not the prototype. Also, just noticed a big whoops up there.

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.