I am creating a instance of a class using the following code:
test = new function(){
...
}
However, base has no prototype because it was created from an anonymous function (I'm guessing this is the reason?). This leaves me unable to create any public functions for the instance.
You could argue I could get around this by simply doing:
function testClass(){
...
}
test = new testClass()
and then attaching public functions to testClass.
But this forces me to do unnecessary namespacing. In particular, if I were to name my class this.is.a.space, then what would I call my instance? this.is.a.spaceInstance? this.is.a.space.Instance?
Is there a convention for this sort of thing?
You can still code the anonymous function and use .__proto__ to access its prototype like this:
test = new function(){
...
};
test.__proto__.foo = function() { return 1 };
However, you only have one instance so you could also just use:
test.foo = function() { return 1 };
I'm not completely sure what exactly you're trying to accomplish, but as for the naming, it is usual to name the class like SomeClass and other variables (like instances) along the lines of someVariable. JavaScript is case-sensitive so you could use TestClass/testClass.
Related
Background
I've been working with OOP style Javascript for the past few months, starting with just dissecting open source libraries. It seems like they mostly follow the same pattern, except that I've seen two ways of handling private functions, and I'm wondering which is the best (best as in best practice, or better for reasons I might not know about).
Example Code
Below is a very stripped down skeleton of the pattern I'm using. If you'll note, there are two different forms of private functions.
The first is attached to the prototype like public functions, but is prefixed with an _.
The second is just a function who's scope is only accessible by the class.
(function(window) {
window.FooBarClass = (function() {
var Class = function( params ) {
this._init( params );
}
/***************************************/
/************* INITIALIZE **************/
/***************************************/
Class.prototype._init = function( params ) {
// DO SETUP STUFF
};
/***************************************/
/********** PUBLIC FUNCTIONS ***********/
/***************************************/
Class.prototype.doThings = function() {
// DO STUFF
};
/***************************************/
/****** PRIVATE FUNCTIONS 1ST WAY ******/
/***************************************/
Class.prototype._createSection = function( params ) {
// DO STUFF
};
/***************************************/
/****** PRIVATE FUNCTIONS 2ND WAY ******/
/***************************************/
function correctTwoDigitYear( variable ) {
// DO STUFF
}
return Class;
}());
}(window));
Question
Which of these is preferable, and why?
JS doesn't actually have private methods, though as you've seen you can limit access to functions and variables by closing over their scope.
In the end, if it's on the prototype, it's not private--regardless of naming convention (leading underscores, etc). So if you really want to limit access to something, do NOT put it on the prototype.
The second pattern, putting functions in the local scope, is preferable because it's actually private. It's not really OOP though.
The first pattern, putting functions in underscored properties on the prototype, is preferable because they are actual methods that get their this passed implicitly like you expect of a method. By being instance methods, they are available to any module that needs them, instead of being restricted by scope, which can be beneficial in larger projects. And of course methods are important in OOP as they offer dynamic dispatch if you want to use polymorphism.
Also prototype methods are (were?) a bit better optimised, so they were chosen if you need to squeeze out the last bit of performance, though in practice you won't see much difference to a plain function call.
any method that is attached to the prototype property of a function is accessible by the object or by the child class. SO,
class.prototype.__init
cannot be considered as a private method.
It can be accesible by the object or it can be modified by extending the class
ex:
var someClass = (function () {
var Class = function( params ) {
this._init( params );
}
Class.prototype._init = function( params ) {
console.log("Hello World");
};
return Class;
} ());
var extendSomeClass = someClass;
extendSomeClass.prototype._init = function () {
console.log("Hey there");
}
var obj = new extendSomeClass(); // this wil print "Hey there"
In the example that you have posted, the _init is acting as a constructor, hence the property associated with it is made public (though the naming convention suggests a private member). But to follow a private access, a closure scope should be the best practice.
example:
var fooClass = (function () {
var Class = function () {
if(this._init) {
this._init.apply(this, arguments);
}
}
Class.prototype.hello = function () {
log("hello world");
}
function log(args) {
console.log(args);
}
}());
In the example above the function log is a private method and cannot be modified/overridden outside the scope.
Say I have a type called MyObject and I want to add the method myMethod to it. Is there any difference (logically, but also performance-wise) between the following ways?
#1
function MyObject() {
...
}
MyObject.prototype.myMethod = function() {
...
};
#2
function MyObject() {
this.myMethod = function() {
...
};
...
}
#3
function MyObject() {
this.myMethod = myMethod;
...
}
function myMethod() {
...
}
I wouldn't mind knowing if there's a performance difference - e.g. if way #2 is costly because it defines the function separately every time an object is instantiated - but I'm mostly concerned with whether the results are equivalent.
In addition, with method #2, isn't this the same way that a class-level/static method would be defined, so does it have the danger of being called like MyObject.myMethod();? If myMethod used this and it was called on MyObject rather than an instance of MyObject, I would think this would cause issues. So does the compiler/interpreter check to see whether this is present or would it throw an error?
#1: This is the preferred way to write "class-level" methods. This saves on memory (as you'll see in #2) and JS engines can know that each instance will have this method and optimize around that.
#2: You're right, this one is more costly because it creates a new function for each instance. The difference here is that you can include private variables generated in the constructor. For example:
function MyObject() {
var name = 'Me';
this.getName = function() {
return name;
};
}
Only things created in the constructor will have access to name.
#3: This approach is largely the same as #1 but I imagine that JavaScript engines are not written to optimize for this case (but this might not be true and may change, JS engines are constantly evolving). This also creates a global function (assuming you're not using a module system) which can create major issues later.
Option 1: You can call my method without instantiating MyObject:
MyObject.prototype.myMethod();
Options 2: You must instantiate the MyObject to be able to access myMethod.
This will fail:
MyObject2.myMethod();
Uncaught TypeError: undefined is not a function
This will not:
var myObject = new MyObject2();
myObject.myMethod();
Check out the code pen: http://codepen.io/sessa/pen/tfqln
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'");
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 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. :)