Javascript inheritance with a priviledged function - javascript

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

Related

Using this or new in JS?

I've got 3 codes :
var control = new Control();
function Control() {
this.doSomethingElse = function() {...}
this.doSomething = function () {
control.doSomethingElse();
}
}
Or
var control = new Control();
function Control() {
var self = this;
this.doSomethingElse = function() {...}
this.doSomething = function () {
self.doSomethingElse();
}
}
Or
var control = Control();
function Control() {
var self = this;
this.doSomethingElse = function() {...}
this.doSomething = function () {
self.doSomethingElse();
}
return self;
}
Important : The function is a controller, and just declared once. Then I'm using "control" everywhere in my code...
I was wondering if the control.doSomethingElse() was slow ?
In the end, what is the right thing to do and/or the fastest code in those exemple ?
Thanks !
The first is wrong - an object should never internally use the variable name by which it is known outside. Other code could change that variable to point to something else, breaking this code.
The third is also wrong - when calling Control() without new the assignments to this.foo inside will end up getting attached to the global object (except in strict mode, where there's no implicit this on bare function calls, so the assignment to this.doSomethingElse tries to attach to undefined, causing a runtime error).
That only leaves the second as appropriate, but ultimately it's a question of correctness, not performance.
Do not define methods in constructor - that means defining them every time an instance is created. Use Control.prototype.foo = function() {} instead. Also you do not need to return this if you're using new operator - that's the whole point of new operator.
The recommended approach is this:
function MyClass(param1) {
// Here we're changing the specific instance of an object
this.property1 = param1;
}
// Prototype will be shared with all instances of the object
// any modifications to prototype WILL be shared by all instances
MyClass.prototype.printProperty1 = function() {
console.log(this.property1);
}
var instance = new MyClass("Hello world!");
instance.printProperty1(); // Prints hello world
To understand this code, you need to understand javascript's prototype-based inheritance model. When you create instance of MyClass, you get a new object that inherits any properties present in MyClass.prototype. Read more about it.
Also I wonder:
The function is a controller, and just declared once.
If you're not using this multiple times, you don't need to create something like class. You can do this instead:
var control = {doSomething:function() { ... }};
I assume you are used to Java, where everything must be a class, whether it makes sense or not. Javascript is different, you can also make single objects or functions as you need.

Javascript Prototype What is Correct?

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

How should you inherit from EventEmitter in node?

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'");

How to create a function in class that is not going to the prototyped function in TypeScript?

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.

javascript: constructor function vs revealing module pattern for single use

I have come to understand that constructor functions can be instantiated to create new objects in javascript which has its own _proto_ property and also giving the property 'prototype' to the constructor function.
function MyController() {
var controllerName = 'initialcontroller';
function init() {
console.log(controllerName);
}
this.init = init;
}
Here, init can be called like this:
var mycontroller = new MyController();
mycontroller.init();
Supposing I am only instantiating only once and never again, isn't this an overkill if I don't intend to use all the prototype properties being provided by the MyController.prototype ?
Question: Instead, can i not code like this using the revealing module pattern?
var myController = function() {
var controllerName = 'initialcontroller';
function init() {
console.log(controllerName);
}
return {
init : init
}
}();
Here, init can be called like this:
myController.init();
In this case, if I try to access any property inside myController that is not present, the javascript engine won't try to find whether the property exists anywhere in the prototype chain, thus saving my time.
Or is there any other advantages of instantiating a function that i am overlooking?
If you simply want a "singleton"-like object with some methods and other properties, you could just use an object literal to simplify things even more:
var myController = {
init: function (foo) {
// do something with foo or whatever
}
}
myController.init("bar");
Or - if you need some "private" internal state, use the regular revealing module pattern:
var myController = (function () {
var internal = "i am private";
return {
init: function () {
// blah blah
}
};
}());
myController.init();
About the prototype lookup time: Yeah, theoretically, the lookup traverses up the prototype chain when you're trying to access a non-existing property. Theoretically, this might be a tiny bit faster for plain ol' Object instances that have "no" specific constructor. In reality, this performance impact should be quite negligible. Don't attempt to optimize here unless you REALLY need it. :)

Categories

Resources