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. :)
Related
I am trying to wrap my head around different Module pattern declinations. I see different ways of writing these modules and exposing their data.
I'm expecting information on advantages/disadvantages, better patterns not described here, use cases for each of them.
A) Object literal wrapped in a self invoking function, firing off with an init method: (source)
(function() {
var MyModule = {
settings: {
someProperty: 'value';
}
init: function() {
someMethod();
}
someMethod: function() {
// ...
}
};
MyModule.init();
})();
This is an example of a simple "Tweet This" utility I built. Am I using this pattern correctly? So far it's the only one that I have actual experience in writing.
B) Module as a namespaced self-invoking anonymous function: (source)
var MyModule = (function () {
var MyObj = {}
function privateMethod() {
// ...
}
MyObj.someProperty = 1;
MyObj.moduleMethod = function () {
// ...
};
return MyObj;
}());
Are there any advantages/disadvantages over the previous style? Also, what would be the implications of using object literal notation here instead of the dot syntax in the example? Object literal seems cleaner and easier, but I'm not really aware of the proper use cases for each?
C) Module as a namespaced self-invoking anonymous function, but only exposing desired results through a return block: (source)
var MyModule = (function() {
var myPrivateVar, myPrivateMethod;
myPrivateVar = 0;
myPrivateMethod = function(foo) {
console.log(foo);
};
return {
myPublicVar: "foo",
myPublicFunction: function(bar) {
myPrivateVar++;
myPrivateMethod(bar);
}
};
})();
Similar to the previous style, but instead of exposing an entire object with all of it's properties/methods, we're just exposing specific bits of data through a return statement.
D) Module as a function wrapped in a self-invoking anonymous function, with nested functions acting as methods. The module is exposed through the window object, then constructed via the new keyword: (source)
(function(window, undefined) {
function MyModule() {
this.myMethod = function myMethod() {
// ...
};
this.myOtherMethod = function myOtherMethod() {
// ...
};
}
window.MyModule = MyModule;
})(window);
var myModule = new MyModule();
myModule.myMethod();
myModule.myOtherMethod();
I'm assuming the strength of this pattern is if the module is a 'template' of sorts where multiple entities may need to exist within an application. Any specific examples of a good use case for this?
All of these are using the same pattern just in slightly different ways.
A) Object literal wrapped in a self invoking function, firing off with an init method:
This is fine if you don't intend to allow anyone else to access a chunk of code. You don't even have to have an init function. Wrapping your code in an IIFE (immediately invoked function expression) prevents global namespace pollution and allows the use of "private" variables. In my opinion, this is just good practice, not a module.
B) Module as a namespaced self-invoking anonymous function:
This is what people mean when they're talking about the module pattern. It gives you private variables and functions then exposes those through a public interface. That interface just so happens to be called MyObj in your example.
C) Module as a namespaced self-invoking anonymous function, but only exposing desired results through a return block:
This is actually exactly the same thing a B. The only difference is that methods on the interface can't directly reference the interface itself like you can in B. Example:
MyObj.methodA = function() {
return MyObj.methodB();
};
That will work with the previous example because you have a name to reference it but is only useful when you expect public methods to be called using anything other than the returned object as the execution context. i.e, setTimeout(MyModule.methodA) (that will be called with the global context so this.methodB() would not work as intended.
D) Module as a function wrapped in a self-invoking anonymous function, with nested functions acting as methods. The module is exposed through the window object, then constructed via the new keyword:
Same thing as the previous 2 except for 2 minor differences. window is passed as an argument because it has historically been true that it's faster to access a local variable than a global variable because the engine doesn't have to climb up the scope chain. However, most JS engines these days optimize accessing window since it's common and a known object. Likewise, undefined is given as a parameter with nothing passed as an argument. This ensures you have a correct undefined value. The reasoning behind this is that technically, you can assign any value to undefined in non-strict mode. Meaning some 3rd party could write undefined = true; and suddenly all of your undefined checks are failing.
The other difference is that you're returning a function instead of an object. The bonus behind this is that you can have private variables which are shared in each instance of an object, as well as private variables per instance. Example:
var count = 0;
function MyObject(id) {
var myID = id;
count++;
// Private ID
this.getID = function() {
return myID;
};
// Number of instances that have been created
this.getCount = function() {
return count;
};
}
The downside to this is that you aren't attaching methods to the prototype. This means that the JS engine has to create a brand new function for every single instance of the object. If it was on the prototype, all instances would share the same functions but could not have individual private variables.
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.
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
Conside the following JavaScript code. The function definitions all seem to achieve the same thing. Is there any recommended convention for defining the functions which are then 'revealed' in the return dictionary object?
var testModule = (function(){
var counter = 0;
var localFunc1 = function() {
return "local 1";
}
function localFunc2() {
return "local 2";
}
this.localFunc3 = function() {
return "local 3";
}
localFunc4 = function() {
return "local 4";
}
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
})();
I don't think that there is any real preferred method. The most common setup I've seen involves creating all of your methods as local (using var) then returning an object that exposes the public methods.
A couple of things to note:
this.localFunc3 will only work if your object is instantiated with the 'new' keyword
when returning your object, remove the () from each function so that you are returning a reference to the function and not the function's returned value
localFunc4 will be global since it has no 'var' keyword in front of it
When working with a module pattern like this, I tend to go for something along the lines of:
var Obj = ( function () {
var private_static = 'this value is static';
return function () {
//-- create return object
var _self = {};
//-- create private variables
var private_variable = 'this value is private';
var func1 = function () {
return 'value 1';
};
//-- attach public methods
_self.func1 = func1;
//-- return the object
return _self;
};
} )();
Some notes about this method:
allows for private static variables (if you don't need private static variables, you can remove the closure)
by creating the _self reference first, you can pass a self reference to any objects instantiated from within that need a reference to their parent
I like that I can reference all internal functions without _self.whatever or this.whatever, ignoring whether or not they are private or public
The definitions do not achieve the exact same thing.
var localFunc1 and function localFunc2 do the same thing, they create functions only available inside your outer function.
this.localFunc3 and localFunc4 are not really local functions: they both belong to the window object (this in that context is window, and localFunc4 is declared without the var statement).
So, the latter two don't even need to be exposed on your returned object, since they're already global. And, actually, you are not exposing any functions on your return object, you are exposing their return values, since you invoke each of them. Were you trying to do this?
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
Note: I recommend you watch this video where Douglas Crockford explains the multiple ways to deal with inheritance in JavaScript. I believe you are looking for what he calls "parasitic inheritance".
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.