I was reading over this small article to understand inheriting from EventEmitter, but I'm a little confused.
He does this:
function Door() {
events.EventEmitter.call(this);
this.open = function() {
this.emit('open');
};
}
Door.prototype.__proto__ = events.EventEmitter.prototype;
https://gist.github.com/chevex/7646362
Why does he manually invoke the EventEmitter constructor with his own constructor's this? Also, why does he set the prototype of his contsructor's prototype to the prototype of EventEmitter? That's super confusing to me.
Then someone in the comments suggested he do this instead, which seemed more elegant:
function Door() {
events.EventEmitter.call(this);
this.open = function () {
this.emit('open');
}
}
util.inherits(Door, events.EventEmitter);
https://gist.github.com/chevex/7646447
This seems WAY cleaner than the other way, though that's probably just because I fail to understand what's going on in the first instance. I would not be surprised if util.inherits is doing the same thing as the first example.
The second one at least makes a little sense to me, but I still don't understand why they don't just do this:
function Door() {
this.open = function () {
this.emit('open');
}
}
Door.prototype = new events.EventEmitter();
https://gist.github.com/chevex/7646524
Can anyone explain to me what the differences between all of these approaches is and why in the first two they invoke .call(this) on the EventEmitter constructor? I omitted that line while trying out the examples and they still worked.
The third example is not generally correct: that creates one single EventEmitter instance for all door instances.
Let's imagine a simple case:
var Foo = function() {
// each Foo instance has a unique id
this.id = Math.random();
}
Foo.prototype.doFoo = function() { console.log("Foo!"); }
Suppose we want to create a Bar constructor that inherits from Foo and adds some new properties. If you follow your final example:
var Bar = function() {
this.something = 5;
}
Bar.prototype = new Foo();
This is wrong because all Bar instance will have the same id property. Instead, we must call the parent constructor for each instance:
var Bar = function() {
Foo.call(this); // set unique `id` on `this`
this.something = 5;
}
Bar.prototype = Object.create(Foo.prototype);
Note that the final line here is the same as Bar.prototype.__proto__ = Foo.prototype; because Object.create creates a new object whose __proto__ is set to the Object.create argument.
Why does he manually invoke the EventEmitter constructor with his own constructor's this?
This is necessary to make sure whatever code is in the EventEmitter constructor function is executed. Some classes might not do anything interesting in the constructor, but others will have important code there, so you should always do this to make sure that code runs the same way it would run if you had just made a new EventEmitter directly with var emitter = new EventEmitter;
In some languages (such as Java) this "constructor chaining" type behavior is implicit, but in JavaScript it must be explicitly done.
Exactly how to set up inheritance in JavaScript comes down to an "it's complicated" answer and others can probably do it more justice than I. There are also several viable variations and people differ on which is preferable. However, FYI the source for util.inherits is here and the best in-depth examination of all the flavors of doing this I have seen is in this video: Douglas Crockford: Advanced JavaScript. Basically, watch that in it's entirety periodically until it sinks in.
Places to look for reference. If you fully understand how all these works, you've mastered it (it still turns my brain into a pretzel at some point along the way)
Backbone's extend helper function (which is Backbone.Model.extend, Backbone.View.extend, etc)
CoffeeScript's class support
node.js's util.extend
function Door() {
events.EventEmitter.call(this);
}
Door.prototype.__proto__ = events.EventEmitter.prototype;
In this case using events.EventEmitter.call(this) is like using super in languages which have one. It's actually can be omitted in simple cases, but it will break domain support on current node version and maybe something else in future versions.
Setting __proto__ just sets up the prototype chain. At can be also done like this:
Door.prototype = Object.create(events.EventEmitter.prototype);
but in this case you also need to set constructor property manually.
util.inherits(Door, events.EventEmitter);
This is the idiomatic way of inheriting in node. So you are better to use this. But what it does is basically the same as above.
function Door() {
}
Door.prototype = new events.EventEmitter();
And this is the WRONG way, don't use it! You will end with having events shared between instances in some versions of node.
The Node v6.3.1 documentation states about util.inherits(constructor, superConstructor):
Usage of util.inherits() is discouraged. Please use the ES6 class and extends keywords to get language level inheritance support. Also note that the two styles are semantically incompatible.
The following code shows how to inherit from EventEmitter with Typescript:
import { EventEmitter } from "events"
class Person extends EventEmitter {
constructor(public name: string) {
super()
}
}
let person = new Person("Bob")
person.on("speak", function (said: string) {
console.log(`${this.name} said: ${said}`)
})
person.emit("speak", "'hello'") // prints "Bob said: 'hello'"
The previous code will transpile into the following ES6 code:
"use strict";
const events = require("events");
class Person extends events.EventEmitter {
constructor(name) {
super();
this.name = name;
}
}
let person = new Person("Bob");
person.on("speak", function (said) { console.log(`${this.name} said: ${said}`); });
person.emit("speak", "'hello'");
Related
Javascript's new Proxy feature offers some interesting features for debugging. For example you can "defend" an object by putting it behind a Proxy with a get handler that throws if you access an undefined property. This helps catch typos and other kinds of mistakes.
This could be used something like this:
class Something {
constructor()
{
this.foo = "bar";
allObjects.push(this);
}
};
function defend(o)
{
return new Proxy(o, DebugCheckHandler);
};
let rawSomething = new Something();
let defendedSomething = defend(rawSomething);
Code can be diligently written to only deal in terms of defendedSomething. However in this example, the Something constructor passes this somewhere else (to allObjects). This ends up having the same effect as using both rawSomething and defendedSomething across the codebase.
Problems then arise from the fact the proxy reference does not equal its original reference, since rawSomething !== defendedSomething. For example, allObjects.includes(defendedSomething) will return false if it contains rawSomething, because includes does a strict === check.
Is there a good way to solve this without making too many changes to the code?
Instead of letting the new operator call [[Construct]], which produces a real instance, you can:
Create an object which inherits from the prototype of the constructor.
Use it as the handler of the proxy.
Call the constructor passing the proxy as the this value.
function Something() {
this.foo = "bar";
allObjects.push(this);
}
function defendIntanceOf(C) {
var p = new Proxy(Object.create(C.prototype), DebugCheckHandler);
C.call(p);
return p;
};
let defendedSomething = defendIntanceOf(Something);
Note I used the function syntax instead of the class one in order to be able to use Function.call to call [[Call]] with a custom this value.
Iirc, the only way to influence the this value in a constructor - which is what you need here - is through subclassing. I believe (but can't test) that the following should work:
function Defended() {
return new Proxy(this, DebugCheckHandler);
// ^^^^ will become the subclass instance
}
class Something extends Defended {
// ^^^^^^^^^^^^^^^^ these…
constructor() {
super();
// ^^^^^^^ …should be the only changes necessary
// and `this` is now a Proxy exotic object
this.foo = "bar";
allObjects.push(this);
}
};
let defendedSomething = new Something();
Hey guys i have a question regarding prototype in javascript.
Which of the following is the correct and best way to use prototype and why?
var myClass = function(){
this.anotherFunction();
}
myClass.prototype.anotherFunction = function(){
console.log('my prototype function');
}
var foo = new myClass(); // which automaticaly performs the function
OR
var myClass = function(){
}
myClass.prototype.anotherFunction = function(){
console.log('my prototype function');
}
var foo = new myClass();
foo.anotherFunction(); // performs the function only when called
Thanks!
The first implementation calls a method directly from the constructor. These methods are quite often some kind of initialization methods that build the needed inner state of the this context. In non JavaScript appropriate OOP speak this would mean that a method is called directly from your class constructor that builds up some initial state.
The second implementation exposes the prototype function anotherFunction as part of the public interface.
In short: Both variants are correct but implement different concepts
When i create a function inside the class, TS compiler makes that function as prototyped function for example.
class MyClass {
getExample()
{
}
}
the resultant is
var MyClass = (function() {
function MyClass() {}
MyClass.prototype.getExample = function() {};
return MyClass;
})();
but what i need is
function MyClass() {
this.getExample = function() {
}
}
is it possible to get a function like this ?
Take a look at this JQFAQ.com link, here is the answer for your question 'How to create a function in class that is not going to the prototyped function in TypeScript?', and there are more FAQs available.
I had a look at TypeScript (like the online playground... prefer writing my own JS, though :P)As far as I can tell, what you want to do can be done quite easily, I've tried a few things myself and this worked like a charm for me:
class Greeter {
greeting: string;
closureMethod;
constructor (message: string) {
this.greeting = message;
var that = this;
var closureMethod = function()
{
console.log(that.greeting);
};
this.closureMethod = closureMethod;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var another = new Greeter('Foobar');
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function()
{
greeter.closureMethod();
another.closureMethod();
}
document.body.appendChild(button)
Which worked, but even shorter (and this works, too)
class Greeter {
greeting: string;
closureMethod;//define property here, no type
constructor (message: string) {
this.greeting = message;
var that = this;
this.closureMethod = function()
{
console.log(that.greeting);
};
}
greet() {
return "Hello, " + this.greeting;
}
}
Both produce the same result: a constructor that defines a method over and over, for each new instance (which, honestly, is not a great idea).
As you can see, it accesses the instance using that, rather than this, which is the only upside of creating the same method over and over... as long as you have a good reason to do so. But I'm not going off in a rant on this.
The code above works, it generates a constructor function like the one you wanted.
Methods you add to the constructor in TypeScript will be added as instance methods.
Methods you add outside the constructor and within the class will be added to the prototype of the object. This is the preferred way if you are "newing" up several instances of the class as it saves on memory. But when you do this you need to make sure you have access that you need to instances memebrs and the proper "this", which you can do by setting them in advance.
I recommend considering prototypes first, then falling back to instance if you truly need them for methods. If its a singleton object, then it really doesn't matter.
However ... when you create classes in TypeScript the concept of private and public does not translate to the emitted JavaScript. So keep this in mind as you are exposing every instance member in JavaScript. I prefer to use a pattern like the Module Pattern in JavaScript, which hides internal variables/methods and exposes only what I want to be accessible. You can get this with TypeScript by creating a function that returns the accessible members of an object (no classes). Just thought I'd mention the alternative.
You can do it like this:
class MyClass {
static getSomething() {
}
}
The static keyword means it is not a prototype method and you won't need to call it on an instance - just call it with:
MyClass.getSomething();
Of course, this may not be what you want - but you'll need to share why you need it to make that clearer.
I'm simplifying my example to get to the heart of my question. I have a base Javascript class with a privileged function. I really need to hide myVar from being seen and I also really want to inherit from baseClass.
function baseClass() {
var myVar = new coolClass();
this.myPrivileged = function() {
myVar.coolFunction();
}
}
The problem I get is that I'm trying to inherit like so:
function childClass() {
}
childClass.prototype = new baseClass();
childClass.prototype.reallyCoolFunction = function() {//Really cool stuff}
but only one instance of myVar will ever be created and that will not work because coolClass has instance dependant properties.
so if I do this:
var x = new childClass();
var y = new childClass();
both x and y will have the same instance of baseClass.myVar
So as far as I can figure I have two choices:
Make the myPrivileged function a prototype function and expose myVar
Copy and paste the internals of baseClass into childClass (which makes me want to gag)
I'm no javascript guru so I was hoping someone would have a good idea.
Thanks in advance
First of all, you don't need to create an instance of baseClass just to setup inheritance. You're creating an instance of coolClass that is never used. Use a surrogate constructor
function childClass() {
...
}
function surrogateCtor() {
}
surrogateCtor.prototype = baseClass;
childClass.prototype = new surogateCtor();
In your childClass, you need to call the parent's constructor
function childClass() {
baseClass.call(this);
}
That will ensure that the base class is initialized every time you instantiate the child class http://jsfiddle.net/mendesjuan/h2ypL/
See my post about inheritance in JS http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
Today, I saw a JavaScript pattern I have never seen in my whole life. I cannot tell the purpose of using this pattern. It seems wrong to me, but I want to be a little conservative. It might be some awesome pattern I never saw before.
function Dog() {
Dog.prototype.bark = function () {
alert('woof!');
}
this.bark = function () {
Dog.prototype.bark();
}
this.bark();
}
First, I'm not a fan for making methods (as privileged members) inside the constructor for no reason. It would cause creating functions every time when an instance is created. Second, in this code snippet, it also calls the prototype name "Dog", instead of "this". This makes me super confused.
Anyone knows what good about it?
Thanks!
Grace
This is a very bad idea, for a great number of reasons. A few of which are:
Adding methods to the prototype in the constructor will cause the prototype method to be replaced for all instances, everytime you instantiate a new Dog.
Calling Dog.prototype.bark() means that this will be Dog.prototype and not your instance of Dog, which can cause serious issues.
this.bark = function () { Dog.prototype.bark(); } is some serious WTF. Because this.bark will already evaluate to the prototype method making this unnecessary. And calling it like this actually destroys the natural this value, as mentioned in #2.
Here is what is should be:
function Dog() {
this.makeSound();
};
Dog.prototype.bark = function() {
alert('woof');
};
Dog.prototype.makeSound = function() {
this.bark();
};
Or alternatively, without the prototype at all:
function Dog() {
this.bark = function() {
alert('woof');
};
this.makeSound = function() {
this.bark();
};
this.makeSound();
};
I would not trust this snippet of yours at all.
Sorry for the VERY late reply, but if you really want to add the prototypes within the constructor AND not have it recreated whenever a new instance is created, you could do this:
function Dog() {
if (!Dog.prototype.bark) {
Dog.prototype = function() {
console.log('woof');
}
}
this.bark();
}
I still probably wouldn't use this method, but I have some across instances where this method was a option when dealing with 3rd party frameworks (the dodgy kind).