How do we use 'inheritance' in Node.JS? I heard that prototype is similar to interfaces in java. But I have no idea how to use it!
Although there are various ways of performing inheritance and OO in javascript, in Node.js you would typically use the built in util.inherits function to create a constructor which inherits from another.
See http://book.mixu.net/ch6.html for a good discussion on this subject.
for example:
var util = require("util");
var events = require("events");
function MyOwnClass() {
// ... your code.
}
util.inherits(MyOwnClass, events.EventEmitter);
Creating an object constructor in pure JS:
They're just functions like any other JS function but invoked with the new keyword.
function Constructor(){ //constructors are typically capitalized
this.public = function(){ alert(private); }
var private = "Untouchable outside of this func scope.";
}
Constructor.static = function(){ alert('Callable as "Constructor.static()"'); }
var instance = new Constructor();
Inheritance:
function SubConstructor(){
this.anotherMethod(){ alert('nothing special'); }
}
function SubConstructor.prototype = new Constructor();
var instance = new SubConstructor();
instance.public(); //alerts that private string
The key difference is that prototypal inheritance comes from objects, rather than the things that build them.
One disadvantage is that there's no pretty way to write something that makes inheritance of instance vars like private possible.
The whopping gigantor mega-advantage, however, is that we can mess with the prototype without impacting the super constructor, changing a method or property for every object even after they've been built. This is rarely done in practice in higher-level code since it would make for an awfully confusing API but it can be handy for under-the-hood type stuff where you might want to share a changing value across a set of instances without just making it global.
The reason we get this post-instantiated behavior is because JS inheritance actually operates on a lookup process where any method call runs up the chain of instances and their constructor prototype properties until it finds the method called or quits. This can actually get slow if you go absolutely insane with cascading inheritance (which is widely regarded as an anti-pattern anyway).
I don't actually hit prototype specifically for inheritacne a lot myself, instead preferring to build up objects via a more composited approach but it's very handy when you need it and offers a lot of less obvious utility. For instance when you have an object that would be useful to you if only one property were different, but you don't want to touch the original.
var originInstance = {
originValue:'only on origin',
theOneProperty:'that would make this old object useful if it were different'
}
function Pseudoclone(){
this.theOneProperty = "which is now this value";
}
Pseudoclone.prototype = originInstance;
var newInstance = new Psuedoclone();
//accesses originInstance.originValue but its own theOneProperty
There are more modern convenience methods like Object.create but only function constructors give you the option to encapsulate private/instance vars so I tend to favor them since 9 times out of 10 anything not requiring encapsulation will just be an object literal anyway.
Overriding and Call Object Order:
( function Constructor(){
var private = "public referencing private";
this.myMethod = function(){ alert(private); }
} ).prototype = { myMethod:function(){ alert('prototype'); };
var instance = new Constructor();
instance.myMethod = function(){ alert(private); }
instance.myMethod();//"undefined"
Note: the parens around the constructor allow it to be defined and evaluated in one spot so I could treat it like an object on the same line.
myMethod is alerting "undefined" because an externally overwritten method is defined outside of the constructor's closure which is what effective makes internal vars private-like. So you can replace the method but you won't have access to what it did.
Now let's do some commenting.
( function Constructor(){
var private = "public referencing private";
this.myMethod = function(){ alert(private); }
} ).prototype = { myMethod:function(){ alert('prototype'); };
var instance = new Constructor();
//instance.myMethod = function(){ alert(private); }
instance.myMethod();//"public referencing private"
and...
( function Constructor(){
var private = "public referencing private";
//this.myMethod = function(){ alert(private); }
} ).prototype = { myMethod:function(){ alert('prototype'); };
var instance = new Constructor();
//instance.myMethod = function(){ alert(private); }
instance.myMethod();//"prototype"
Note that prototype methods also don't have access to that internal private var for the same reason. It's all about whether something was defined in the constructor itself. Note that params passed to the constructor will also effectively be private instance vars which can be handy for doing things like overriding a set of default options.
Couple More Details
It's actually not necessary to use parens when invoking with new unless you have required parameters but I tend to leave them in out of habit (it works to think of them as functions that fire and then leave an object representing the scope of that firing behind) and figured it would be less alien to a Java dev than new Constructor;
Also, with any constructor that requires params, I like to add default values internally with something like:
var param = param || '';
That way you can pass the constructor into convenience methods like Node's util.inherit without undefined values breaking things for you.
Params are also effectively private persistent instance vars just like any var defined in a constructor.
Oh and object literals (objects defined with { key:'value' }) are probably best thought of as roughly equivalent to this:
var instance = new Object();
instance.key = 'value';
With a little help from Coffeescript, we can achieve it much easier.
For e.g.: to extend a class:
class Animal
constructor: (#name) ->
alive: ->
false
class Parrot extends Animal
constructor: ->
super("Parrot")
dead: ->
not #alive()
Static property:
class Animal
#find: (name) ->
Animal.find("Parrot")
Instance property:
class Animal
price: 5
sell: (customer) ->
animal = new Animal
animal.sell(new Customer)
I just take the sample code Classes in CoffeeScript. You can learn more about CoffeeScript at its official site: http://coffeescript.org/
Related
I have a class instance (in my case the class is URL), called req_url. URL has a property that has a setter for one of its properties (search) that is implemented in a way that is problematic for me (doesn't just set the given value but does something to it first).
How can I override that setter without creating a class that inherits from URL (and then create a different setter)?
defineProperty doesn't work since it works at the Object level. I want to to do it on that specific type level.
Whenever you have an instance whose setter you want to bypass, calling Object.defineProperty on the instance to set the property does work:
class Foo {
set prop(arg) {
console.log('setter invoked');
}
}
const f = new Foo();
Object.defineProperty(f, 'prop', { value: 'val' });
console.log(f.prop);
It won't affect any object, it'll only affect objects you explicitly call Object.defineProperty with. The collisions with other objects you seem to be worried about won't occur.
Another (stranger) option would be to delete the setter on the prototype, though if the class is used elsewhere, outside of your code, it could cause problems:
class Foo {
set prop(arg) {
console.log('setter invoked');
}
}
delete Foo.prototype.prop;
const f = new Foo();
f.prop = 'val';
console.log(f.prop);
I'm curious what the difference is between the following OOP javascript techniques. They seem to end up doing the same thing but is one considered better than the other?
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
vs
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title;
};
return book;
}
var myBook = Book('War and Peace');
alert(myBook.getTitle())
The second one doesn't really create an instance, it simply returns an object. That means you can't take advantage of operators like instanceof. Eg. with the first case you can do if (myBook instanceof Book) to check if the variable is a type of Book, while with the second example this would fail.
If you want to specify your object methods in the constructor, this is the proper way to do it:
function Book(title) {
this.title = title;
this.getTitle = function () {
return this.title;
};
}
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
While in this example the both behave the exact same way, there are differences. With closure-based implementation you can have private variables and methods (just don't expose them in the this object). So you can do something such as:
function Book(title) {
var title_;
this.getTitle = function() {
return title_;
};
this.setTitle = function(title) {
title_ = title;
};
// should use the setter in case it does something else than just assign
this.setTitle(title);
}
Code outside of the Book function can not access the member variable directly, they have to use the accessors.
Other big difference is performance; Prototype based classing is usually much faster, due to some overhead included in using closures. You can read about the performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx
Which is better can sometimes be defined by the context of their usage.
Three constraints of how I choose between Prototype and Closure methods of coding (I actively use both):
Performance/Resources
Compression requirements
Project Management
1. Performance/Resources
For a single instance of the object, either method is fine. Any speed advantages would most likely be negligible.
If I am instantiating 100,000 of these, like building a book library, then the Prototype Method would be preferred. All the .prototype. functions would only be created once, instead of these functions being created 100,000 times if using the Closure Method. Resources are not infinite.
2. Compression
Use the Closure Method if compression efficiency is important (ex: most browser libraries/modules). See below for explanation:
Compression - Prototype Method
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
Is YUI compressed to
function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title};
A savings of about 18% (all spaces/tabs/returns). This method requires variables/functions to be exposed (this.variable=value) so every prototype function can access them. As such, these variables/functions can't be optimized in compression.
Compression - Closure Method
function Book(title) {
var title = title; // use var instead of this.title to make this a local variable
this.getTitle = function () {
return title;
};
}
Is YUI compressed to
function Book(a){var a=a;this.getTitle=function(){return a}};
A savings of about 33%. Local variables can be optimized. In a large module, with many support functions, this can have significant savings in compression.
3. Project Management
In a project with multiple developers, who could be working on the same module, I prefer the Prototype Method for that module, if not constrained by performance or compression.
For browser development, I can override the producton.prototype.aFunction from "production.js" in my own "test.js" (read in afterwords) for the purpose of testing or development, without having to modify the "production.js", which may be in active development by a different developer.
I'm not a big fan of complex GIT repository checkout/branch/merge/conflict flow. I prefer simple.
Also, the ability to redefine or "hijack" a module's function by a testbench can be beneficial, but too complicated to address here...
The former method is how JavaScript was intended to be used. The latter is the more modern technique, popularised in part by Douglas Crockford. This technique is much more flexible.
You could also do:
function Book(title) {
return {
getTitle: function () {
return title;
}
}
}
The returned object would just have an accessor called getTitle, which would return the argument, held in closure.
Crockford has a good page on Private Members in JavaScript - definitely worth a read to see the different options.
It's also a little bit about re-usability under the hood. In the first example with the Function.prototype property usage all the instances of the Book function-object will share the same copy of the getTitle method. While the second snippet will make the Book function execution create and keep in the heap 'bookshelf' different copies of the local closurable book object.
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title += '#';
};
return book;
}
var myBook = Book('War and Peace');
var myAnotherBook = Book('Anna Karenina');
alert(myBook.getTitle()); // War and Peace#
alert(myBook.getTitle()); // War and Peace##
alert(myAnotherBook.getTitle()); // Anna Karenina#
alert(myBook.getTitle());// War and Peace###
The prototype members exist in the only copy for all the new instances of the object on the other hand. So this is one more subtle difference between them that is not very obvious from the first sigh due to the closure trick.
here is an article about this
in general Book inharets from Book.prototype. In first example you add function to getTitle Book.prototype
If I create an object property via Object.defineProperty() with a getter/setter method (an accessor descriptor) like:
var myObj = function myObj() {
var myFoo = 'bar';
Object.defineProperty(this, 'foo', {
enumerable: true,
get: function() {
return myFoo;
},
set: function(newValue) {
myFoo = newValue;
}
});
return this;
};
If I do something like var f = new myObj(); console.log(f) in Node, the output is something like:
{ foo: [Getter/Setter] }
console.log(f.foo) gets the proper 'bar' value, but is there a way to indicate that upon logging/inspecting, it should just run the getter and show the value?
First, it's important to understand why this happens. The logging functions don't run getters by design because your getter function could have side effects, whereas the logging function can guarantee that getting the value of a primitive doesn't.
When you pass an object to console.log, it's really just passing it off to the util module's inspect to format into human-readable text. If we look there, we see that the very first thing it does is check the property descriptor, and if the property has a getter, it doesn't run it. We can also see that this behavior is unconditional – there's no option to turn it off.
So to force getters to run, you have two options.
The simplest is to convert your object to a string before handing it off to console.log. Just call JSON.stringify(obj, null, 4), which will produce reasonably human-readable output (but not nearly as nice as util.inspect's). However, you have to take care to ensure that your object doesn't have any circular references and doesn't do something undesired in a toJSON function.
The other option is to implement a inspect function on your object. If util.inspect sees a function called inspect on an object, it will run that function and use its output. Since the output is entirely up to you, it's a much more involved to produce output that looks like what you'd normally get.
I'd probably start by borrowing code from util and stripping out the part about checking for getters.
This behavior is certainly intentional. I know I wouldn't want all the getter functions on an object running whenever I logged that object; that sounds like potential a debugging landmine, where debugging could alter the state of my program.
However, if indeed that is the behavior you want, you can add a new function:
Object.getPrototypeOf(console).logWithGetters = function(obj) {
var output = {};
var propNames = Object.getOwnPropertyNames(obj);
for(var i=0; i<propNames.length; ++i) {
var name = propNames[i];
var prop = Object.getOwnPropertyDescriptor(obj, name);
if(prop.get) {
output[name] = prop.get();
} else {
output[name] = obj[name];
}
}
// set output proto to input proto; does not work in some IE
// this is not necessary, but may sometimes be helpful
output.__proto__ = obj.__proto__;
return output;
}
This allows you to do console.logWithGetters(f) and get the output you want. It searches through an object's properties for getters (checking for the existence of Object.getOwnPropertyDescriptor(obj, propName).get) and runs them. The output for each property is stored in a new object, which is logged.
Note that this is a bit of a hacky implementation, as it doesn't climb the object's prototype chain.
This is how I used to utilize inheritance in Entity Framework (POCO):
ctx.Animals // base class instances (all instances)
ctx.Animals.OfType<Cat> // inherited class Cat's instances only
ctx.Animals.OfType<Dog> // inherited class Dog's instances only
This is the only similar way I found in MongoDb (MongoDb reference):
var query = Query.EQ("_t", "Cat");
var cursor = collection.FindAs<Animal>(query);
Note in the latter case I have to deal with discriminator ("_t") and hardcode my class name, that is not quite convenient and looks awful. If I miss the query I got an exception on enumeration attempt. Have I missed something? My suggestion was the document Db which stores objects 'as is' should handle inheritance easily.
Assuming your discriminators are functioning (_t is stored correctly for each document) then I think this is what you are looking for.
var results = collection.AsQueryable<Animal>().OfType<Cat>
Returns only those documents that are of type 'Cat'.
Well, a document db does in fact store objects "as is" - i.e. without the notion of objects belonging to some particular class. That's why you need _t when you want the deserializer to know which subclass to instantiate.
In your case, I suggest you come up with a discriminator for each subclass, instead of relying on the class name. This way, you can rename classes etc. without worrying about a hardcoded string somewhere.
You could do something like this:
public abstract class SomeBaseClass
{
public const string FirstSubClass = "first";
public const string SecondSubClass = "second";
}
[BsonDiscriminator(SomeBaseClass.FirstSubClass)]
public class FirstSubClass { ... }
and then
var entireCollection = db.GetCollection<FirstSubClass>("coll");
var subs = entireCollection.Find(Query.Eq("_t", SomeBaseClass.FirstSubClass));
From your link:
The one case where you must call RegisterClassMap yourself (even without arguments) is when you are using a polymorphic class hierarchy: in this case you must register all the known subclasses to guarantee that the discriminators get registered.
Register class maps for your base class and each one of your derived classes:
BsonClassMap.RegisterClassMap<Animal>();
BsonClassMap.RegisterClassMap<Cat>();
BsonClassMap.RegisterClassMap<Dog>();
Make sure that your collection is of type of your base class:
collection = db.GetCollection<Animal>("Animals");
Find using your query. The conversion to the corresponding child class is done automatically:
var query = Query.EQ("_t", "Cat");
var cursor = collection.Find(query);
If the only concern is hardcoding class name, you can do something like this:
collection = db.GetCollection<Animal>("Animals");
var query = Query.EQ("_t", typeof(Cat).Name);
var cursor = collection.Find(query);
Take a look on the documentation
http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/#scalar-and-hierarchical-discriminators
The main reason you might choose to use hierarchical discriminators is because it makes it possibly to query for all instances of any class in the hierarchy. For example, to read all the Cat documents we can write:
var query = Query.EQ("_t", "Cat");
var cursor = collection.FindAs<Animal>(query);
foreach (var cat in cursor) {
// process cat
}
I have a module Vehicle that contains general vehicle info. I have another module Car, which adds more functionality to Vehicle object.
// Pseudo code only. The final functions do not have to resemble this
var vehicle = require('vehicle')
vehicle.terrain = 'Land'
var car = vehicle.createCar()
// car and anotherCar will have unique Car-related values,
// but will use the same Vehicle info
var anotherCar = vehicle.createCar()
I am looking at using Object.create for the Car module, but not sure where the Object.create calls should go.
Should I have a constructor in the Car module that takes an instance of a Vehicle object and does an Object.create with the Vehicle instance as the prototype?
Or should the Object.create happen in a function on the Vehicle object, like createCar? My issue with this way, is Car should care that it's derived from Vehicle, Vehicle shouldn't know Car requires that.
Or even if Object.create is the right approach.
Please, any examples and best practices would be greatly appreciated.
Update:
I changed the example to better reflect the inheritance problem I'm trying to solve.
imo, you're describing a builder pattern rather than inheritance I think -- I wouldn't use object.create for this. A VehicleBuilder is responsible for constructing an object that has certain properties associated with it.
var builder = new VehicleBuilder();
builder.terrain = 'Land';
builder.wheelCount = 2;
builder.color = "blue";
var motorcycle = builder.createVehicle();
It might use something like:
VehicleBuilder.prototype.createVehicle = function(){
var me = this;
return new Vehicle({
color: me.color,
terrain: me.terrain,
wheelCount: me.wheelCount
});
}
If you look at the typical inheritance pattern in js, its something much more well defined and uses two primary patterns in node. One is util.inherits. Its code is simple: https://github.com/joyent/node/blob/master/lib/util.js#L423-428
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: { value: ctor, enumerable: false }
});
};
And the second is calling the parent constructor in the child class constructor.
function ChildClass(){
SuperClass.call(this); // here
}
Example: https://github.com/joyent/node/blob/master/lib/stream.js#L25-28
So instead of a vehicle taking a bunch of properties or another object in its constructor, you use the prototype chain and the constructor to define custom subclass behavior.
I would recommend a different approach
// foo.js
var topic = require("topic");
topic.name = "History";
topic.emit("message");
topic.on("message", function() { /* ... */ });
// topic.js
var events = require("events");
var Topic = function() {
};
// inherit from eventEmitter
Topic.prototype = new events.EventEmitter();
exports.module = new Topic;
You have a good EventEmitter to do message passing for you. I recommend you just extend the prototype of Topic with it.
Why not just use js native prototype based inheritance? Expose your constructor directly using module.exports:
//vehicle.js
module.exports = function() {
//make this a vehicle somehow
}
Then:
// Pseudo code only. The final functions do not have to resemble this
var Vehicle = require('vehicle')
Vehicle.terrain = 'Land'
var car = new Vehicle()
// car and anotherCar will have unique Car-related values,
// but will use the same Vehicle info
var anotherCar = new Vehicle()