I have been experimenting using static methods in Javascript. Instead of having objects inherit from a prototype, I use duck-typing a lot harder.
var Controller = {};
Controller.getData = function() {//return data};
// and then in use:
var page = route.getPage();
require([page], function(Controller) {
Controller.getData();
});
I could do this same by creating new objects with the Controller prototype:
function Controller() {};
Controller.prototype.getData = function() {//return data};
// and then in use:
var page = route.getPage();
require([page], function(Controller) {
var controller = new Controller();
controller.getData();
});
My gut feeling is that the static method will be faster, but I have no clue. In general, what are the performance discrepancies between these two methods?
TLDR; basically this question but for Javascript.
Edit: So there is a bit of a performance difference when you are instantiating the class vs. calling the "static" version, but the difference doesn't really warrant you making any changes to your code (premature optimization) unless you are seeing an actual slow down.
As demonstrated in the basic jsperf test I setup, there really isn't much of a difference, performance wise. You should make the decision based on whether or not you want the context (this) to refer to your base class or not.
Related
I am using Protractor with pageObject concept to do e2e testing.
However, I have difficulties to understand why creating new objects is needed for each pageObject?
Show you my question by code
Currently, I define the pageObject in pageObj.js as
var PageObj = function () {
this.method1 = function() { //whatever content };
}
module.exports = PageObj;
and invoking it in test spec file as
var PageObj = require('./pageObject/pageObj.js');
var pageObj = new PageObj();
//use pageObj's method here;
pageObj.method1();
However, I think this way below is simpler, why shouldn't I use this?
Define the same method in pageObj.js
```
module.exports = {
method1: function() {
//whatever content;
},
Invoke it as
var pageObj = require('./pageObject/pageObj.js');
//use pageObj's method here;
pageObj.method1();
Sometimes you might have multiple tests using the same page object and you might want to store there data representing current or changing state of page during one test or suite of tests. Using it as a class/constructor function allows you to have a clear state between every test.
If your take works for you for now and the future and doesn't limit you it's completely fine, just for these more complex cases you might need to have to use instanced page objects to achieve what you need.
At our company we prefer to stick to one pattern to not have to adjust to use page object as an object here and as constructor function there. So to keep it more uniform across our tests we just follow the recommended style + this pattern has already settled and it's easier to switch between projects if they follow the same guidelines.
As #Tom mentions, using an object literal is fine, but can be limiting. I use them if I don't have to extend other pages (eg. a basePage). I also feel like instantiating page objects in the spec is a bit clunky, so I opt for a solution somewhere in between..
var PageObj = function() {
this.method1 = function() { //whatever content };
};
module.exports = new PageObj();
And then your spec...
var pageObj = require('./pageObject/pageObja ');
//use pageObj's method here;
pageObj.method1();
Since there is a benefit to use prototype for methods if you need to create lots of them, do you get the same effect and benefit when you create an object with methods that close over "this" in the constructor function?
See the following code:
(function(){
var Planet = function(){
var self = this;
var API = {
publicInterfaceMethodA:function(){
self.privateProtoMethodA();
},
publicInterfaceMethodB:function(){}
};
return API;
};
Planet.prototype = {
privateProtoMethod:function(){ },
privateProtoMethodA:function(){ },
privateProtoMethodB:function(){ },
privateProtoMethodC:function(){ },
privateProtoMethodD:function(){ },
privateProtoMethodE:function(){ }
};
var mars = new Planet();
}());
Let's say I have 100 "private" methods on the prototype, for every instance I create I only want to expose these few public api methods, but I want to retain the benefit of using the prototype for internal methods so that I dont "copy" 100 methods to "this" for every instance created.
From what I can see, this is not how people usually do it, am I missing something here or do you get the same benefit without returning "this" in the constructor and exposing the entire prototype?
Thanks
When I started to develop seriously in JS, I also often used the var self = this;, because I was used to it from the various jQuery tutorials and I also tried your approach and others to simulate private methods.
Personally I don't like both anymore.
While it is true that mars is not an instance of Planet, this is - in my opinion - not a real problem, because I normally test for api features and not that often if an object is an instance of a certain constructor.
To private methods/members: when your projects grows and becomes larger you probably want to start to do unit tests. If you e.g. have 100 private methods and only 10 public ones, creating good unit test can become really problematic. For unit test you would like to test as less dependencies as possible.
Thats why I changed my mind and preferred to create a clear documentation of api with jsdoc using the annotation to mark methods/members if they are private instead of not over really hiding them.
Sometime it could also be useful not just be able to replace public methods base on the situation, but also private ones.
There are for sure valid situations for your approach, but if you just use it to protect the function from misuse, you probably should think about it.
To the var self = this;: As long as someFunction.bind(element) does not create performance problems I prefer to use bind (there is a polyfill for older browsers). With that you can avoid deep nesting of e.g. callbacks and you don't need to keep in mind that you need to use self where the expected keyword would be this.
How about something like this?
(function(){
var Planet = function(){
var self = this;
self.constructor.methods = {
A: function(){ console.log('Constructor Method A called'); },
B: function(){ },
C: function(){ },
D: function(){ },
E: function(){ }
};
var API = {
publicInterfaceMethodA: function(){
return self.constructor.methods.A.call(this);
},
publicInterfaceMethodB: function(){}
};
return API;
};
var mars = new Planet();
mars.publicInterfaceMethodA();
}());
The methods are attached to the Planet function and then called by the mars instance.
I recently got familiar with the Revealing Module Pattern (RMP) and I've read quite a few articles about it.
It seems like a very good pattern and I would like to start using it in a big project. In the project I'm using : Jquery, KO, requireJS, Jquery Mobile, JayData. It seems to me like it'll be a good fit for the KO ViewModels.
In specific I'd like to use THIS version of it.
One thing I could not find are disadvantages for using this pattern, is it because there aren't any (I find it hard to believe)?
What should I consider before starting to use it?
The Revealing Module Pattern (RMP) creates objects that don't behave well with respect to overriding. As a consequence, objects made using the RMP don't work well as prototypes. So if you're using RMP to create objects that are going to be used in an inheritance chain, just don't. This point of view is my own, in opposition to those proponents of the Revealing Prototype Pattern.
To see the bad inheritance behavior, take the following example of a url builder:
function rmpUrlBuilder(){
var _urlBase = "http://my.default.domain/";
var _build = function(relUrl){
return _urlBase + relUrl;
};
return {
urlBase: _urlBase,
build: _build
}
}
Setting aside the question of why you would use RMP for an object with no private components, note that if you take the returned object and override urlBase with "http://stackoverflow.com", you would expect the behavior of build() to change appropriately. It doesn't, as seen in the following:
var builder = new rmpUrlBuilder();
builder.urlBase = "http://stackoverflow.com";
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions"
Contrast the behavior with the following url builder implementation
function urlBuilder = function(){
return {
urlBase: "http://my.default.domain/".
build: function(relUrl){ return this.urlBase + relUrl;}
}
}
var builder = new urlBuilder();
builder.urlBase = "http://stackoverflow.com";
console.log(builder.build()); // prints "http://stackoverflow.com/questions"
which behaves correctly.
You can correct the Revealing Module Pattern's behavior by using this scope as in the following
function rmpUrlBuilder(){
var _urlBase = "http://my.default.domain/";
var _build = function(relUrl){
return this.urlBase + relUrl;
};
return {
urlBase: _urlBase,
build: _build
}
}
but that rather defeats the purpose of the Revealing Module Pattern. For more details, see my blog post http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/
I read the article that #nemesv referenced me to (Thanks :)) and I thinks there is one more disadvantage that was not mentioned, so I thought I'd add it here for reference. Here is a quote from the article:
Disadvantages
A disadvantage of this pattern is that if a private function refers to
a public function, that public function can't be overridden if a patch
is necessary. This is because the private function will continue to
refer to the private implementation and the pattern doesn't apply to
public members, only to functions.
Public object members which refer to private variables are also
subject to the no-patch rule notes above.
As a result of this, modules created with the Revealing Module pattern
may be more fragile than those created with the original Module
pattern, so care should be taken during usage.
And my addition:
You can't use inheritance with this pattern. For example:
var Obj = function(){
//do some constructor stuff
}
var InheritingObj = function(){
//do some constructor stuff
}
InheritingObj.prototype = new Obj();
InheritingObj.prototype.constructor = InheritingObj;
This a simple example for inheritance in js, but when using the Revealing Prototype Pattern (archived here) you'll need to do this:
InheritingObj.prototype = (function(){
//some prototype stuff here
}());
which will override you inheritance.
Introductory reading:
Prototypes as "classes"
OO JS
Following the patterns described above I create libraries/APIs as the following
var Proto = {
constructor: function () {
this.works = true;
},
method: function () {
return this.works;
}
};
Now for library users to interact with my prototypes (which do not supply factory functions) they have to instantiate and initialize the object
// instantiate
var p = Object.create(Proto);
// initialize
p.constructor();
This is an unfriendly and verbose way of forcing users to instantiate and initialize my objects.
personally since I use pd in all my applications I have the following sugar
// instantiate or initialize
var p = Proto.new();
// or without bolting onto Object.prototype
var p = pd.new(Proto);
However I think it's unkind to force pd onto users so I'm not sure what's the best way to make my libraries usable.
People create new instances of Proto and call .constructor themself
Force people to use pd
Give .create style factory functions
Give up and use new <Function> and .prototype
1 and 2 have already been mentioned.
3 would basically be
Proto.create = pd.new.bind(pd, Proto);
4 would make me sad but confirming to a known standard way of doing things increases usability.
Generally when using non-standard OO patterns what are the easiest mechanisms to allow people to use my library in their application?
I'm currently tempted to say
// here is my Prototype
Proto;
// here is how you instantiate a new instance
var p = Object.create(Proto);
// here is how you initialize it
// yes instantiation and initialization are seperate and should be.
p.constructor();
// Want sugar, use pd.new
For now, you probably make it easiest on your library clients if you use a small API that helps you with building a traditional constructor function, using syntax that looks almost like prototypes-as-classes. Example API usage:
// Superclass
var Person = Class.extend({
constructor: function (name) {
this.name = name;
},
describe: function() {
return "Person called "+this.name;
}
});
// Subclass
var Worker = Person.extend({
constructor: function (name, title) {
Worker.super.constructor.call(this, name);
this.title = title;
},
describe: function () {
return Worker.super.describe.call(this)+" ("+this.title+")";
}
});
var jane = new Worker("Jane", "CTO");
Implementations:
Simple JavaScript Inheritance
I’ve reimplemented Resig’s API, in a way that is possibly easier to understand: rauschma/class-js
I think the way to go is providing the new(Prototype, [arguments]) function as per the "use pd" option. It should even not be that bad from a dependency point of view (since you could have packaged this function separately anyway and is has just a couple of lines of code)
Offering a special function also fits in a sort of historic perspective. If you go way back to Smalltalk or even in more recent cases like Python you have separate functions for object creation (new) and initialization (init, the constructor) and the only only reason we don't notice the separation is because they provide syntactic sugar for object instantiation.
I'm interesting in improving my javascript code to be properly OOP.... currently I tend to do something like this:
jQuery(document).ready(function () {
Page.form = (function () {
return {
//generate a new PDF
generatePDF: function () {
},
//Update the list of PDFs available for download
updatePDFDownloads: function () {
},
/*
* Field specific functionality
*/
field: (function () {
return {
//show the edit prompt
edit: function (id, name) {
},
//refresh the value of a field with the latest from the database
refresh: function (id) {
}
};
}())
};
}());
});
In the end it's just mainly organized functions I suppose... what's a good resource where I can learn to program javascript in an OOP manner, or what suggestions would you have for improving my current style of programming?
It seems like I should do a sort of model prototype and have my form object inherit from that prototype.
(I'm using jQuery instead of $ because of conflicts with prototypeJS)
Your question is quite broad so I don't think a complete answer is possible here. But here are a few points.
Regarding the code you have shown. You're jumping a couple of redundant hoops.
Unless you're accessing the DOM in some way, there is no need to wrap your code in jQuery(document).ready()
There is no need to return an object from a self calling anonymous function unless you're closing over some private functions or data
The object you have created can be created more simply (a good thing) like this
var Page = {
form: {
//generate a new PDF
generatePDF: function () {
},
//Update the list of PDFs available for download
updatePDFDownloads: function () {
},
/*
* Field specific functionality
*/
field: {
//show the edit prompt
edit: function (id, name) {
},
//refresh the value of a field with the latest from the database
refresh: function (id) {
}
}
}
};
It's easier to read and less confusing, only do things that buy you something. see cargo cult programming
Here's an example using a self calling anonymous function to create private members
var Obj = (function() {
privateFunction( param ) {
// do something with param
}
var privateVar = 10;
return {
// publicMethod has access to privateFunction and privateVar
publicMethod: function() {
return privateFunction( privateVar );
}
}
})();
The structure you have used, object literals are very good, as you say, at grouping a set of functions (methods) and properties. This is a kind of namespace. It is also a way of creating a Singleton. You may also want to create many objects of the same Class.
JavaScript doesn't have classes like traditional OO languages (I'll get to that) but at the simplest level it's very easy to create a 'template' for creating objects of a particular type. These 'templates' are normal functions called constructors.
// a constructor
// it creates a drink with a particular thirst quenchingness
function Drink( quenchingness ) {
this.quenchingness = quenchingness;
}
// all drinks created with the Drink constructor get the chill method
// which works on their own particular quenchingness
Drink.prototype.chill = function() {
this.quenchingness *= 2; //twice as thirst quenching
}
var orange = new Drink( 10 );
var beer = new Drink( 125 );
var i_will_have = ( orange.quenchingness > beer.quenchingness )
? orange
: beer; //beer
var beer2 = new Drink( 125 );
beer2.chill();
var i_will_have = ( beer2.quenchingness > beer.quenchingness )
? beer2
: beer; //beer2 - it's been chilled!
There's a lot to know about constructors. You'll have to search around. There are lots of examples on SO.
Inheritance, the foundation of OO, is not that intuitive in js because it is prototypal. I won't go into that here because you will more than likely not use js's native prototypal inheritance paradigm directly.
This is because there are libraries that mimic classical inheritance very effectively, Prototype (inheritance) or mootools (Class) for example. There are others.
Many say that inheritance is overused in OO and that you should favour composition and this brings me to what I initially set out to recommend when I started this rambling answer.
Design patterns in JavaScript are as useful as in any OO language and you should familiarise yourself with them
I recommend you read Pro JavaScript Design Patterns.
There, that's it
Some good sources for Object-Oriented JavaScript and JavaScript in general...
Online Articles
How to "properly" create a custom object in JavaScript?
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
http://mckoss.com/jscript/object.htm
http://ejohn.org/blog/simple-javascript-inheritance/
JavaScript: How To Get Private, Privileged, Public And Static Members (Properties And Methods)
Books
JavaScript: The Good Parts - Douglas Crockford
Object-Oriented JavaScript - Stoyan Stefanov
I hope this helps.
Hristo
There isn't one correct way... Some people use a framework to define their object, I like to just extend prototype directly. Anyhow, I wanted to say that Oran Looney has some good posts on OO mechanics in JS:
http://oranlooney.com/classes-and-objects-javascript/
Its also worth looking at his other articles:
http://oranlooney.com/deep-copy-javascript/
http://oranlooney.com/functional-javascript/
The top 3 I suggest to read is
JavaScript and Object Oriented Programming (OOP)
Classical Inheritance in JavaScript
Prototypal Inheritance in JavaScript
Have a nice reading!
The code we are using follows this basic structure:
//Create and define Global NameSpace Object
( function(GlobalObject, $, undefined)
{
GlobalObject.Method = function()
{
///<summary></summary>
}
}) (GlobalObject = GlobalObject || {}, jQuery);
//New object for specific functionality
( function(Functionality.Events, $, undefined)
{
//Member Variables
var Variable; // (Used for) , (type)
// Initialize
GlobalObject.Functionality.Events.Init = function()
{
///<summary></summary>
}
// public method
this.PublicMethod = function(oParam)
{
///<summary></summary>
///<param type=""></param>
}
// protected method (typically define in global object, but can be made available from here)
GlobalObject.Functionality.ProtectedMethod = function()
{
///<summary></summary>
}
// internal method (typically define in global object, but can be made available from here)
GlobalObject.InternalMethod = function()
{
///<summary></summary>
}
// private method
var privateMethod = function()
{
///<summary></summary>
}
}) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery )
The strength to this is that it initializes the Global object automatically, allows you to maintain the intergrity of your code, and organizes each piece of functionality into a specific grouping by your definition. This structure is solid, presenting all of the basic syntactical things you would expect from OOP without the key words. Even setting up intelisense is possible with javascript, and then defining each peice and referencing them makes writing javascript cleaner and more manageable. Hope this layout helps!
I dont think it matters what language you use, good OOP is good OOP. I like to split up my concerns as much as possible by using an MVC architecture. Since JavaScript is very event based, I also use the observer design pattern mostly.
Heres a tutorial you can read about MVC using jQuery.