Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

node.js, require() and prototypal-inheritance

node.js, require() and prototypal-inheritance

Problem

I'm pretty new to node.js, and probably javascript as well, so feel free to point out anything that seems awkward. I'm here to learn.

Here's what I'm trying to do:

  • "John" object should inherit everything from "Client" object, including functions
  • Use Object.create() instead of "new" keyword in instantiating new objects and inheritance

Here is a single file test that worked:

var sys=require('sys');
var Client = {
  ip: null,
  stream : null,
  state: "Connecting",
  eyes: 2,
  legs: 4,
  name: null,
  toString: function () {
      return this.name + " with " +
      this.eyes + " eyes and " +
      this.legs + " legs, " + this.state + ".";
  }
}
var john = Object.create(Client, {
  name: {value: "John", writable: true},
  state :  {value: "Sleeping", writable: true}
}); 
sys.puts(john); // John with 2 eyes and 4 legs, Sleeping

Here is what happens when I split it up into different files:

---- client.js ----

module.exports = function (instream, inip){
    return  {
         ip: inip,
          stream : instream,
          state: "Connecting",
          eyes: 2,
          legs: 4,
          name: null,
          toString: function () {
            return this.name + " with " +
              this.eyes + " eyes and " +
              this.legs + " legs, " + this.state + ".";
          },
    };

}; 

---- john.js ----

var Client = require("./client");
module.exports = function (inname, instate){
    return Object.create(Client, {
      state : {value: inname, enumerable: false, writable: true},
      name: {value: instate, enumerable: true, writable: true},
    });

};

---- main.js ----

var sys = require("util");
var Client = require("./client")("stream","168.192.0.1");
sys.puts(Client); // null with 2 eyes and 4 legs, Connecting

var john = require("./john")("John","Sleeping");
sys.puts(john); //Function.prototype.toString no generic 
sys.puts(sys.inspect(john)); // { name: 'Sleeping' }
sys.puts(sys.inspect(john, true)); // {name: 'Sleeping', [state]: 'John'}

Questions:

  1. What am I doing something wrong in splitting up the files and in my use of require() that's causing the problems?
  2. Why does the john object have 'Sleeping' as name and 'John' as state? I know it's the order I put the lines, but should it not follow the parameters that I've put in the constructor?
  3. Is there a better way of doing this? I'm inclined to learn Object.create() rather than rely on the "new" keyword.
Problem courtesy of: howdoicodethis

Solution

On #2:

return Object.create(Client, {
  state : {value: inname, enumerable: false, writable: true},
  name: {value: instate, enumerable: true, writable: true},
});

That's a simple mistyping on your side swapping inname and instate.

On #1:

I suspect another slight difference between the original single-file code and the new 3 file code is at fault. A particular comment caught my eye on MDN's page on Object.create, specifically,

Of course, if there is actual initialization code in the Constructor Function, the Object.create cannot reflect it

Your client.js file is producing a constructor function. What you meant to write in john.js is (combining #1 and #2):

return Object.create(Client(), {
  state : {value: instate, enumerable: false, writable: true},
  name: {value: inname, enumerable: true, writable: true},
});

Call the Client function so it returns an object rather than a function, and then create a new object built on top of that.

On #3:

I don't see why you couldn't use this pattern, but you have just demonstrated that it is:

  1. Foreign to how most Javascript objects are created today (though no doubt a faster construction mechanism).
  2. Using a newer syntax (that drops new) so syntax errors don't "jump out" at you like with the old, Java-style syntax.

Just keep that in mind. I'm glad you asked this question, though, because now I know about Object.create. :)

Solution courtesy of: David Ellis

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

node.js, require() and prototypal-inheritance

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×