What is a call from an event issuer?
I am learning Node Js. In my book, I came across a piece of code that says the following:
var EventEmitter = require("events").EventEmitter;
var inherits = require('util').inherits;
//Custom class
function Foo(){
EventEmitter.call(this);
}
inherits(Foo, EventEmitter);
Foo.prototype.connect = function(){
this.emit('connected');
}
var foo = new Foo();
foo.on('connected', function(){
console.log("connected raised!');
}
foo.connect();
My question is what is "ringing" here? Why does the Foo class inherit from EventEmitter? Does this mean that Foo is a child of the Event Emitter? If so, should it be a child of the EventEmitter? I found another question on Stackoverflow regarding calling ( What does EventEmitter.call () do? However, I didn't understand the answer I received ... Thanks
Code Source: Node.js Beginning by Basarat Ali Syed
source to share
Line of code:
EventEmitter.call(this);
calls the constructor of the object you inherit from which allows the EventEmitter code to initialize its part of that object, which is part of the inheritance process in Javascript.
EventEmitter()
is a constructor function for the EventEmitter object. Since you need to call this constructor with the same this
as your new object, you must use either .call()
or .apply()
with this constructor in order to use the correct one this
. Since there are no arguments you pass to the constructor, .call()
this is the easiest way to call it.
You should call the constructor EventEmitter()
to allow it to properly initialize its part of the object created with new Foo()
. When using inheritance in Javascript, multiple separate object definitions use the same object to store their properties and methods, so each of them initializes a lot of its part of the object and initialization is started by calling the constructor of the object you inherited.
Here's a good link to the thread constructors topic .
Some of your comments show that you don't understand what the point of inheritance is in your code. This code allows you to create an object type Foo
that has its own methods, but this ALSO object is an eventEmitter and has all the capabilities of an EventEmitter, so it can trigger events, respond to events, etc ... This is called "inheritance" where you inherit the functionality of some other object with your own custom object. To make inheritance work, your code does two things. With a line of code, inherits(Foo, EventEmitter);
it inherits the prototype of another object so that it will have all the same methods available and with EventEmitter.call(this);
, it calls the constructor of the inherited object so that the object can initialize itself correctly.
You can read a few reference articles on Javascript inheritance:
An introduction to object-oriented JavaScript
Inheritance and prototype chaining
Understanding JavaScript inheritance
source to share
When applied:
inherits(Foo, EventEmitter);
Foo
the prototype is set to EventEmitter.prototype
. Thus, each copy Foo
will have all methods EventEmitter
(e.g. on
, emit
etc.)
When applied:
EventEmitter.call(this)
inside a constructor Foo
, it looks a lot like a call new EventEmitter()
, but instead of creating a new context (variable this
), you pass your context Foo
.
For example, here's the constructor EventEmitter
source :
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
The above-mentioned members of the class ( this._events
and this._eventCount
) are necessary to maintain the private status of the radiator events.
Applying inherits(Foo, EventEmitter)
will just improve the instances Foo
with methods EventEmitter
, however the instances Foo
won't have a very simple and decisive initialization process.
If the superclass has an empty constructor, you can skip this step as it has nothing to assign to a variable this
. Having said that, it is bad practice as you have no guarantee about this.
source to share
This is a ghetto JS way of inheritance as the language does support prototypal inheritance. There is no inheritance at a level not supported by the official language as in other languages, but the fact that we can run functions in different contexts has become a pretty standard hack for shoehorning in an inheritance hierarchy where an instance of your class can also be thought of as an instance of its base class. In other words, in var foo = new Foo()
, foo
you can call an instance foo
and a EventEmitter
. In other languages, you can set up more explicit inheritance, which is supported by the language and the compiler.
.call
is available for all functions and allows the function to be executed, but with a different context. this
in your class foo
refers to the instance foo
that is being instantiated and EventEmitter.call(this);
uses the constructor EventEmitter
, but using your instance foo
as this
inside the constructor.Thus EventEmitter
, anything the constructor would EventEmitter
normally set to a new pure instance EventEmitter
via var emitter = new EventEmitter();
will now actually be set to your instance foo
.
Now this only solves half of the goal of achieving JS pseudo-inheritance. If EventEmitter
there is something in the prototype that we need on the prototype foo
, simply calling the constructor EventEmitter
on your instance is foo
not enough. This is why you also need to call util.inherits(Foo, EventEmitter);
.
util.inherits
simply sets the prototype foo
for a new object that inherits from the prototype EventEmitter
. It also adds a constructor EventEmitter
as a property .super_
to your constructor foo
, which I believe is a Java convention to make it easier to access the underlying constructor (the constructor of the class you inherit). https://github.com/joyent/node/blob/master/lib/util.js#L634-L644
source to share