0

I'm learning to code and I have a question about some sample code I found:

var Comment = new Schema({
    user:userStub,
    time:Date, 
    content: {type:String, required: true, trim:true}
});

From what I learned about OOP, I thought the Comment object instance of Schema would be built like this:

function Schema (user, time, content){

     this.user = user;
     this.time = time;
     this.content = content;
};

var Comment = new Schema (userStub, time, content); 

Anyone know the advantage of building the Comment instance via var Comment = new Schema({ instead? What does the ({ signify? Any help would be greatly appreciated

jherax
  • 5,238
  • 5
  • 38
  • 50
Novice coder
  • 79
  • 2
  • 7

2 Answers2

1

An advantage of doing it this way is that you can change your function without changeing it's signature. Another advantage is that if you have a lot of input parameters with are not all obligatory, you don't have to add default values for parameters you're not using... – @Michiel Reyers

Here is an example on how you can create a new "instance" with an Object Literal as parameter in the constructor function, getting rid of the list of parameters:

function Schema (options) {
     "use strict";
     options = options || {};
     this.user = options.user || "unnamed";
     this.time = options.time || null;
     this.content = options.content || {};
}

In the previous approach, we can create new objects by specifying none, one or all the properties in the entry parameter. Besides the signature of the constructor keeps unchanged:

var comment;

//no arguments
comment = new Schema();

//only one option    
comment = new Schema({ user: "luis" });

//multiple options
comment = new Schema({
    user: "Federico",
    time: new Date(1995, 10 - 1, 31), //october 31, 1995
    content: { type: Types.String, required: true, trim: true }
});

Also you can extend the object, so the constructor function can be more flexible by extending into the instance the new properties in the entry parameter. For this example I'm going to use jQuery (I know, is not in the tag), but you can create a custom method to extend objects without jQuery.

//pointer to the internal Schema
var Schema = (function () {

    //cached default values
    var defaults = {
        user: "unnamed",
        time: null,
        content: {}
    };

    //constructor extensible
    function Schema (options) {
        "use strict";
        //merges @options and @defaults into the instance @this
        jQuery.extend(this, defaults, options);
    }

    //returns the reference to Schema;
    return Schema;
}());

Here we used the Constructor pattern. You can use the Schema and add new properties without having to modify the signature of the constructor. (Also see MODULE pattern).

var comment = new Schema({ user: "Felipe", age: 31 });

An improvement to the previous approach, is to set the default values in the constructor prototype:

//pointer to the internal Schema
var Schema = (function ($) {

    //constructor extensible
    function Schema (options) {
        "use strict";
        //merges @options into the instance @this
        $.extend(this, options);
    }

    //sets the default values
    Schema.prototype = {
      "user": "unnamed",
      "time": null,
      "content": {}
    };

    //returns the reference to Schema;
    return Schema;
}(jQuery));

var comment = new Schema();
console.log(comment);

comment = new Schema({ user: "coco", age: +"d" });
console.log(comment);
jherax
  • 5,238
  • 5
  • 38
  • 50
0

The input type of the constuctor function of Schema is in this case an object, hence the {} notation.

function Schema (o){
     this.user = o.user;
     this.time = o.time;
     this.content = o.content;
};

An object is just a variable just like a string or a number. So you can pass it into a function. But instead of creating an object first, the input object in your example is written in the call like this

mySchema = new Schema({user:'john'});

instead of:

var myObj = {user:'john'};
mySchema = new Schema(myObj);

An advantage of doing it this way is that you can change your function without changeing it's signature. Another advantage is that if you have a lot of input parameters with are not all obligatory, you don't have to add default values for parameters you're not using. For example:

var mySchema1 = new Schema({size:25});
var mySchema2 = new Schema({name:'the best schema ever'});

if the function signature would be:

function Schema(size,name) {
// code here
}

You would have to call:

var mySchema2 = new Schema(0,'the best schema ever');

Where 0 is the default value for size. You can imagine this can be annoying when there are a lot of parameters.

Michiel
  • 4,160
  • 3
  • 30
  • 42