Friday, September 6, 2013

Efficient coding style in ExtJs: Volume 6


Very important links related to this post:

41) Don’t keep reference of ‘this’ to use it in event handler: Generally while working in the inline event handler function of any Extjs component, we don't get the reference of object of the corresponding class by using 'this' keyword. Usually, it gives the object of the component which event handler is this. So, to solve this problem, some developer used to keep the reference of class in some global variables inside the constructor or initComponent of that class and then use this global variable in inline handlers to get the object of the corresponding class. But, this is wrong practice and we should follow as given here. Click here to get complete idea about this.

42) Try to use client side caching: local storage, session storage, sqllite etc.: If we are using Html5, we can save some of our data on client side (not on cookies) and use it if use revisit that page again. Thus, we can avoid unnecessary hit to server and database. In extJs, we can use proxy to handle such cache. There are two types of proxies in ExtJs: ClientProxy and ServerProxy. ClientProxy is used to handle client side caching. There are three types of clientProxies:

·         Ext.data.proxy.LocalStorage: The LocalStorageProxy uses the new HTML5 localStorage API to load and save data into the client browser. The localStorage sets the fields on the domain; this means you can close the browser and reopen it, and the data will be in the localStorage. The localStorage is used for long-term storage; it is also accessible in all browser tabs/windows.

·         Ext.data.proxy.SessionStorage: The SessionStorageProxy uses the new HTML5 sessionStorage API to load and save data into the client browser. sessionStorage sets the fields on the window; this means that all the data will be lost when you close the browser, even if the website remains open in another browser window. The sessionStorage data is confined to the browser window that it was created in.

·         Ext.data.proxy.SessionStorage: MemoryProxy is a helper proxy. Usually, it is used to load some inline data into a store. The MemoryProxy contents are lost in every page refresh. It can be useful to load temporary data.

Beside these, some browser like chrome etc also supports a special type of client side database i.e. SqlLite and it can be used to store some data on client side. Thus, by using these techniques, we can enhance our application’s performance.

43) Don’t use Array.isArray(): Array.isArray(anyObject) function is used  to decide that whether “anyObject” is an array object. This function is working as needed in Chrome but not in IE. IE is not able to identify this function and giving error. We should use “instanceof” instead of this function to fulfill the same purpose. “instanceof” is working in both IE and Chrome.

44)      Be careful about Date formatting: While dealing with date parsing below are date string formats which are supported by IE and chrome.
                                 var dateString = "03/20/2008";                                 
                                 var dateString = "2008/03/20";                                                 
                                 var dateString = "03-20-2008";                                  
                                 var dateString = "March 20, 2008";                                         
                                 var dateString = "Mar 20, 2008";                                              
                                 var dateString = "Oct 2, 2011";

But  do not use  var dateString = "Oct/02/2011"; it not supported by IE, although works in chrome. It was being used in application I corrected it.

45)      Don’t forget followings: Below are the some points that we should not forget while sending our code in production:

·         No trailing commas.
·         Use multiline comments instead of single line comments even if you are commenting a single line.
·         No debuggers left uncommented in the code.
·         Don’t miss any semicolon where it is expected.
·         Don’t use consol.log() in production code.

Gyes! This is not the end of the list of Efficient coding style in ExtJs and javascript. I will keep updating this list whenever I got a new point. I am requesting to all readers that if you got any point that I have not mentioned in all the posts under heading “Efficient coding style in ExtJs”, please send me your points through the feedback section at the bottom of this post.

46) Avoid using doLayout()

47) Try to use component.suspendLayout() and component.resumeLayout()

48) Declare 3rd party library under require statement on the page where it is needed

49) Stop event bubbling if it is not needed.

50) Try to use component.suspendEvent() or component.resumeEvent() where needed.

51) Keep static text in separate file for localization point of view

52) From Extjs 5 ownward, try to use Reference instead of id or itemId

53) Write proper documentation for each and every class and function using JSDuck

54) Use deep:true to watch the changes in any attribute of a deeply nested object


Efficient coding style in ExtJs: Volume 5


Very important links related to this post:

33) Do not create inline handler functions: Never create inline handler function because The functions used for callbacks and listeners are a common source of problems. They not only take time to create but can also form expensive closures. E.g.

Ext.define(‘MyClass’,{
                constructor: function(config){
                                this.store.on(‘load’, function(){
                ………..;
}, this);
                }
});

The thing to realize is that a new listener function is created each time this constructor runs. This not only takes time but could potentially leak loads of memory though a closure. The preferred pattern looks like this:

Ext.define(‘MyClass’,{
                constructor: function(config){
                                this.store.on(‘load’, this.onStoreLoad, this);
                },
                onStoreLoad: function(){
                                ………;
}
});
In this case the listener function is created once and stored on the class. Each instance will share the same function. The overhead for creating the function is incurred just once and there's no risk of a leaky closure. Even better, this style of coding makes it easy for subclasses to change the listener with a simple override.

34) Proper use of xtype: A common myth is that xtypes provide a performance boost through lazy-instantiation. In general this is not true. As soon as you add an xtype-config to a container it will instantiate the full component, even if it isn't visible.
Whilst xtypes have many great uses they usually have no measurable impact upon application performance or resource consumption.

35) Never use whole Ext-all.js library: Generally Ext-all.js contains huge set of coding for supporting all features and components and we seldom use all features and components of ExtJs. So, it is unnecessary to load such a huge file when we are using its only 60-70% codes. If we minify our production code with the help of sencha command tool, it will automatically copy only required classes from Ext-all.js and paste them in resulting all-classes.js. If we are not using sencha command tool, we should make sure by any other means that we are not loading whole Ext-all.js file.

36) Batching tasks: Try to batch changes that cause re-rendering so that the rendering only happens once at the end. For example, changing a field value in a record will immediately update the grid. If you want to update several fields it's more efficient to batch them: e.g. 

record.beginEdit();
record.set(‘name’, ‘Tom’);
record.set(‘age’, 17);
record.set(‘member’, true);
record.endEdit();

The more fields you change the more noticeable the effect will be.
Another example is adding components to a container. The container will recalculate its layout every time add() is called. Passing multiple items to the same add() call will be much more efficient. E.g.

//slow code
container.add(panel);
container.add(button);
container.add(grid);

//fast
container.add(panel, button, grid);

//using an array is also fast
container.add([panel, button, grid]);

In cases where no other batching mechanism exists it can help to suspend layouts temporarily:

container.suspendLayout = true;
doSomethingToChangeLotsOfLayoutChange();
container.suspendLayout = false;
container.doLayout();

37) Use deferredRender: When using a card layout or tab panel, be careful to consider the deferredRender option. When set totrue it will cause the hidden cards/tabs to be lazily rendered. Rendering will only occur when the hidden items are first shown. When set to false, all cards/tabs will be rendered at the same time, as part of the rendering of the container.
Usually it is better to defer rendering as it helps to break the rendering process up into smaller chunks that won't cause a noticeable delay to the user. However, rendering all the cards/tabs up front can help to improve responsiveness of the UI when the hidden cards/tabs are first shown.

38) Buffered rendering of Grid: When using a grid, if you have a large data set, use buffered rendering.This means that the Store keeps a "prefetch" buffer containing a page of Records which is used when possible to load the Store.
As long as the data set is less than maybe 100,000 rows ( also depends on number of columns in each rows), it's probably best to keep all the data in the client in this prefetch buffer.
It's the rendering of a large HTML table that kills performance. That's just a fact of the HTML table algorithms. Just holding all the data should not cause problems.
What we can do is do "just in time" rendering of the rows in the table as we scroll. To do this, first load the prefetch buffer with all the data. And when that is done, you can then load the Store's main data cache from the prefetch e.g.

myStore = ……{
………….,
Buffered: true, // Tell grid to use a paging scroll manager to scroll and refresh table automatically.
                                perPageCount: 0 // never remove pages from the prefetch buffer;
}

myStore.prefetch({
                                start: 0,
                                limit: 999999,
                                callback: function(){
                                myStore.load(0, 49);
}
});

What that does is prefetches what is hopefully the whole data set. Then the callback loads the Store's main cache (the cache that is mapped to a <table> within the GridPanel) with the first 50 rows. So we only get a small 50 row table. As it scrolls nearly out of view, it is refreshed. This technique works OK in 4.0.x, but it has been really overhauled in 4.1.0 and will be extremely fast and smooth. The buffer-grid example in the grid directory illustrates this technique.
Be aware that it seems that a large number of columns has an effect on the performance of HTML <table> elements too, so avoid columns which do not really need to be present.

39) Populate each tab in tab panel in their beforRender event handler: It is better to populate the tabs in their beforeRender methods. Done correctly it can be very effective at improving performance in applications that have a lot of unrendered components. Although, the time taken to instantiate a component is usually much smaller than the time taken for rendering or layout but if you have huge numbers of unrendered components then it can add up. A tabpanel with many tabs is a good candidate. It should be noted that all I'm proposing is to shuffle time around: cut the time taken for the initial load in favour of slightly slower tab transitions. It's just another technique to have in your arsenal. As ever, the only golden rule for optimizing is to take some meaningful measurements before you do anything else.

40) Use ‘mon’ instead of ‘on’: Both of these keywords are used to register an event handler to its corresponding events. But its better and efficient to use ‘mon’ instead of ‘on’ because This will ensure that the listener is automatically removed when instances of MyClass are destroyed. E.g.

Ext.define(‘MyClass’,{
                                Constructor: function(config){
                                                //this.store.on(‘load’, this.onStoreLoad, this); // this is not good
                                                this.store.mon(‘load’, this.onStoreLoad, this);
                                },
                                onStoreLoad: function(){
                                                ………;
}

});

Efficient coding style in ExtJs: Volume 4

.....being continued from eficient coding style in ExtJs: Volume 3

Very important links related to this post:

25)   Use get/set methods: if you are using config function to declare a variable in a class, ExtJs will automatically create its getters and setters functions and it’s better to use these getters and setters to enhance the code readability. We can also override these functions and can add some more functionality in these functions that will execute if we call these function instead of directly using that variable name. So, always try to use getters and setters of class level variables to use them.

26)  Never create a component with auto layout. A very common mistake is done by most of the ExtJs developer that they creates container but forget to assign some layout to it. Although it works well on some browsers or particular version of a browser, yet in long run it will create problems like causing blank screen or distortion of some of the components. E.g.

Ext.create(‘Ext.panel.Panel’,{
                height: 200,
                width: 500,
                //layout: ‘hbox’,          // anti pattern if layout is not defined
                items:[
                                {
                                                xtype: ‘button’,
                                                id: ‘button1’
                                                flex: 1
},{
                                                xtype: ‘button’,
                                                id: ‘button2’
                                                flex: 1
}
]
});

Here, as layout is not defined in the panel, the height and width of this panel will not be distributed among its component depending on their flex value. The reason behind this is that the layout of containers assures that how the height and width of the container is provided to the components of that container. If we uncomment the line “layout: ‘hbox’”, both the buttons will take the required height and width of their parent container.

27) Avoid using fixed height and width: Never provide fixed height and width to any container or component in your application as this will destroy the layout liquidity of your application. Always provide a height and width to your top most container or view port that will define your screen size and then carefully distribute this dimension to your child components or containers by properly using flex and layouts. Even for defining dimension of your top most container or view port, don’t use hard coded height or width, but calculate it by using ExtJs functions like “Ext.getBody().getViewSize().height” and “Ext.getBody().getViewSize().width” as follows:

Ext.create(“Ext.panel.Panel”,{
                height: Ext.getBody().getViewSize().height,
                width: Ext.getBody().getViewSize().width
});

28) Properly use flex keyword: Flex is a very important keyword used for maintaining liquid layout. It is used to receive the dimension from parent container depending on its value. E.g. if two components are provided with the flex = 1 and flex = 2, then these components will receive dimension from parent container in ration 1:2.
Another important point to be noted here is that the flex value divides only height or width of its parent container but not both according to the ratio of child components’ flex value depending upon the layout type of the parent container. E.g.

Ext.create(‘Ext.panel.Panel’,{
                height: 200,
                width: 500,
                layout: ‘hbox’,         
                items:[
                                {
                                                xtype: ‘button’,
                                                id: ‘button1’
                                                flex: 1
},{
                                                xtype: ‘button’,
                                                id: ‘button2’
                                                flex: 1
}
]
});

Here, as the layout is hbox, only width will be divided in the ratio of flex value of the buttons and height will be 100% for both buttons i.e. width will be 250 and height will be 200 for each of the buttons. Similarly if we change the layout type of the panel to vbox, then width will be 500 and height will 100 for each of the buttons. So, properly and carefully use flex to achieve better liquid layout.

29) Minimize use of minWidth, maxWidth, minHeight, maxHeight: Try to use these attributes in your components only when they are much needed otherwise don’t use them as they are very expensive in terms of layouting of the components. If any of these attribute is encountered in a component, the layout is recalculated. So, these are very expensive.

30) Use code minification by Sencha command tool: Minification is the process of eliminating white space, comments, and other nonessential parts of the JavaScript code to decrease the size of the JavaScript files that need to be transferred from the server to the browser. In addition to the above tasks, minifiers also rename variables to shorter names (but only when it’s safe to do so), such as the parameters D, C, B, A in the preceding code. Minifiers can rename only local variables because renaming globals might break the code. This is why it’s a good practice to use local variables whenever possible. If you use a global variable, such as a DOM reference, more than once or twice in a function, it’s a good practice to assign it to a local variable. This is usually done by a tool (a minifier) such as the ExtJs command tool (in case of application developed in ExtJs)  or Yahoo! YUICompressor or Google’s Closure Compiler (in case of normal javascript application ) and helps speed up the page loading time. It is important to minify the production-ready scripts because this results in significant savings, often cutting the size in half. Provide here the link of your Code Minification Steps

31) Keep Dom Lighter: Always try to keep Dom as lighter as possible to speed up the Dom access and manipulation. This can be done by removing the unnecessary Dom elements. E.g. If we are using card layout and in each card we are showing huge containers and components and if the user is not returning to the previous card, it is better to cache the Dom elements in a variable in your program (so that the required containers and components are not created again and again) and then remove that Dom elements from Dom to make it lighter.

32)   Minimize Dom access: DOM access is expensive; it’s the most common bottleneck when it comes to JavaScript performance. This is because the DOM is usually implemented separately from the JavaScript engine. The bottom line is that DOM access should be reduced to minimum. This means:

·         Avoiding DOM access in loops
·         Assigning DOM references to local variables and working with the locals
·         Using selectors API where available
·         Caching the length when iterating over HTML collections
·         Always try to use ExtJs functions to access or manipulate Dom to gain cross browser facility otherwise code may fail on some browser as each browser has its own way of Dom access.

.....To be continued in Efficient coding style in ExtJs: Volume 5

Very important links related to this post:

Efficient coding style in ExtJs: Volume 1


Very important links related to this post:

Hi gyes. I am working on javascript from years and during this I have identified some important points that we must follow to make our application more responsive, more efficient and bug free. I am presenting these points in my several posts (Links of all these post provided at the top and bottom). My each post related with "Efficient Coding Style" is having 8 points. I have tried my best to explain it and tried to provide example code for better understanding. I am requesting you to please go through examples. These will provide lots of information.

One thing more, if you have any point that I have missed in my posts related with "Efficient Coding Style",  please mention that in feedback column at the bottom, so that I can include that in these list.

Gyes, lets make it one place for all important points that should be followed while coding in Javascript and ExtJs. 

1)      Never use “new” keyword: Using ‘new’ keyword to create an instance of a component or a class in ExtJs is a wrong practice as it does not follow the component life cycle. Always use Ext.create() function to create an object. E.g.

Wrong: var obj = new Ext.panel.Panel();
Right: var obj = Ext.create(‘Ext.panel.Panel’);

2)      Initiate Literals: Do not directly create objects of literals if you want to just create the blank object in javascript like

var stringObj = new String();
var arrayObj = new Array();
var obj = new Object();

These are not right way to create object in javascript, because if we use these process, control will traverse through whole class hierarchy. So, instead of these, we should use following ways to create object of these classes:

var stringObj = ‘’;
var arrayObj = [];
var obj = {};

But you might be inheriting legacy code written by others, so you should be aware of one “feature” of this constructor (or yet another reason not to use it). The feature in question is that the Object() constructor accepts a parameter and, depending on the value passed, it may decide to delegate the object creation to another built-in constructor and return a different object than you expect. E.g.

// Warning: antipatterns ahead
// an empty object
var o = new Object();
console.log(o.constructor === Object); // true
// a number object
var o = new Object(1);
console.log(o.constructor === Number); // true

3)      Smart use of getCmp(): It will return you an item object matching the id you passed it. This will be the fastest method to return an item. All items when created with an id are registered in a single object using their id as a key. So Ext.getCmp( myId) will look up and return theRegistrationObject["myId"]; So it will be very quick.
But it fails if we provided same id to more than one component. In that case, it will return the last one. Beside this, we should not use it to get the object. We should try to use it once and apply its outcome at many places by keeping the outcome in a variable.
If we need to use same id for more than one component, we can use itemId. Let’s finddifference between id and itemId here.

4)      Avoid unnecessary global variables:  The problem with the global variable is that they are shared among all the code in your javascript application or web page. They live in the same global namespace and there is always a chance  of naming collisions – when two separate parts of an application define global variables with the same name but with different purposes. Second drawback of using unnecessary global variable is larger memory consumption as these global variable are generally not garbage collected and they never release memory.

5)      Use var keyword with global variable:  There is one slight difference between globals with var keyword and globals without var keyword – the difference is in the ability to undefine these variables using the delete operator:
Globals created with var ( Those created in the program outside any function) cannot be deleted. E.g.

                // define three globals
var global_var = 1;
global_novar = 2; // antipattern
(function () {
                global_fromfunc = 3; // antipattern
}());
// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

6)      Try to remove unused variables and functions: Do not keep unused variables, functions and unnecessary comments in your code as these will only increase your file size and thus file loading time will be increased.

7)      Avoid object or variable creation in loop: If not needed, do not create even a single variable or object inside any loop because their numbers will increases with every iteration of loop causing memory leakage.

8)      Avoid unnecessary use of panel: Most of the ExtJS applications suffer from panel explosion. Everything is done using a panel, or to be more accurate, everything is done using several panels. The problem is using a panel when there are much more lightweight alternatives. Everyone loves panels but truth be told they're overkill for most parts of a UI. I once saw a UI that displayed a few dozen thumbnail images and each image was rendered as the HTML content of a different panel. All those panel were totally unnecessary. Consider instead...
·         Could you use HTML and CSS instead of a full component? An Ext.Template or Ext.XTemplate might prove helpful.
·         Could you just use a custom Ext.Component? There are various config settings for injecting HTML into a component: autoEl, html, tpl & data.
·         Could you use a DataView to render all of your data instead of a number of individual components?

Efficient coding style in ExtJs: Volume 3

.....being continued from "Efficient coding style in ExtJs: Volume 2"

Very important links related to this post:

17) Proper use of parseInt(): Use parseInt() with proper redix to avoid some unwanted result. E.g.

alert(parseInt("8")); // "Will print 8"
alert(parseInt("08")); // "Will print 0"
alert(parseInt("08,10")); // "Will print 8"
If we use parseInt(“08”), it gives octal value of 08.

So always remember to use second parameter i.e. redix to define the type of number i.e. whether it is decimal, octal or hexadecimal.

18) Be careful about function hoisting: This problem is similar as discussed above in case of variable hoisting. The only difference comes when we use function declaration instead of anonymous function. In case of function declaration, function definition also gets hoisted not only its declaration and improper handling of this will give some unwanted result. E.g.

// antipattern
// for illustration only
// global functions
function foo() {
alert('global foo');
}
function bar() {
alert('global bar');
}
function hoistMe() {
console.log(typeof foo); // "function"
console.log(typeof bar); // "undefined"
foo(); // "local foo"
bar(); // TypeError: bar is not a function
// function declaration:
// variable 'foo' and its implementation both get hoisted
function foo() {
alert('local foo');
}
// function expression:
// only variable 'bar' gets hoisted
// not the implementation
var bar = function () {
alert('local bar');
};
}
hoistMe();

In this example you see that, just like with normal variables, the mere presence of foo and bar anywhere in the hoistMe() function moves them to the top, overwriting the global foo and bar. The difference is that local foo()’s definition is hoisted to the top and works fine; although it’s defined later. The definition of bar() is not hoisted, only its declaration. That’s why until the code execution reaches bar()’s definition, it’s undefined and not usable as a function (while still preventing the global bar() from being “seen” in the scope chain).

19) Adding a property to global namespace: While adding a property to a global name space or global object we should be careful that this may already exist, and we could be overwriting them. Therefore, before adding a property or creating a namespace, it’s best to check first that it doesn’t already exist. E.g.

// unsafe and antipattern
var MYAPP = {};
// better
if (typeof MYAPP === "undefined") {
var MYAPP = {};
}
// or shorter
var MYAPP = MYAPP || {};

To avoid always writing this boilerplate code when creating any member in global name space, we can create some reusable code where we can pass the object to be created and that code will perform above validation and can add or discard our object.

20) Utilize JsLint: JSLint takes a JavaScript source and scans it. If it finds a problem, it returns a message describing the problem and an approximate location within the source. The problem is not necessarily a syntax error, although it often is. JSLint looks at some style conventions as well as structural problems. It does not prove that your program is correct. It just provides another set of eyes to help spot problems. We have to simply paste our script, and it’ll quickly scan for any noticeable issues and errors in our code.
URL: http://www.jslint.com/

21) Avoid with() statement: At first glance, "With" statements seem like a smart idea. The basic concept is that it can be used to provide a shorthand for accessing deeply nested objects. E.g.

with (being.person.man.bodyparts) {  
                                arms = true;  
                                legs = true;  
                 }

Instead of
being.person.man.bodyparts.arms = true;  
                being.person.man.bodyparts.legs= true;

Unfortunately, after some testing, it was found that they "behave very badly when setting new members." Instead, we should use var.
                                 var o = being.person.man.bodyparts;  
                                o.arms = true;  
                o.legs = true;

22) Use ExtJs builtin functions to add or remove elements from Extjs components: To add some objects to an ExtJs container, following code should not be used:

componentObj.items.items[0] = newObject;

Problem in this code:  If this code is used to add something in a container, all built-in tasks of ExtJs are not performed at the time of addition of an object to a container and it may cause some problems.
Solution: add() function of a container object should be used and similarly other built-in functions of a component should be used for corresponding tasks.

23) To retrieve components from ExtJs components: To retrieve an object from  ExtJs component, following code should not be used:

var anObj = componentObject.items.items[0].items.items[1];

Problem: If a new layer, say a panel or a container, is included in the above hierarchy by someone, the whole hierarchy will get disturbed and we will get wrong result.
Solution: We can use Ext.getCmp(componentId) or queryById(componentId) instead of traversing long hierarchy. Although it is little bit slower than traversing hierarchy, yet in this case the hierarchy problem, as discussed above, will not come.

24) Write more readable and debuggable and reusable code: While writing code, developer should create small meaningful classes and functions. Don't try to put large number of lines in a single block. Try to keep code block small so that it can be easily reused and will be more readable.

Thursday, September 5, 2013

Efficient coding style in ExtJs: Volume 2

.....being continued from "Efficient coding style in ExtJs: Volume 1"

Very important links related to this post:

9)  Avoid container over nesting: Always try to avoid unnecessary use of containers because each container creates one level of hierarchy and to access an item at the core, we have to traverse through the hierarchy of these containers. So, try to create your view with minimum possible number of containers.

10)  Functions should be small in size: Every function should be small, crisp and meaningful. Large functions reduces the readability, maintainability, reusability and debugging. Along with these, if an object (that consume huge memory) is instantiated at the start of function, it will live up to the end of function. So, if function is small, its local variables, objects etc will be garbage collected with in very short span of time and thus releasing the memory for other use.

11)  Try to avoid long object references: Always try to avoid using large object references as it will spend much time in traversing the object hierarchy to get the required component. E.g.

    var arrayLength = arrayObj.lenght;
    for( var I = 0; I < arrayLenght; i++){
                //anti pattern
                If(Abc.xyz.foo.bar.againFoo.againBar.finalObj === arrayObj[i]){
                                Alert(‘Anti pattern code’);
                }
   }

The above code can be rewritten in more efficient manner as follows:

    var arrayLength = arrayObj.lenght;
    var obj = Abc.xyz.foo.bar.againFoo.againBar.finalObj;
    for( var I = 0; I < arrayLenght; i++){
                //pattern
                If(obj === arrayObj[i]){
                                Alert(‘pattern code’);
                }
    }

12)  Hoisting problem should be avoided: javascript enables you to have multiple var statements anywhere in a function, and they all act as if the variables were declared at the top of the function. This behaviors  is known as hoisting. This can lead to a logical error when you use a variable and then declare it further in the function. For javascript, as long as the variable in a same scope (same function ), its considered declared even when it is used before the var declaration. E.g.

        // antipattern
        myname = "global"; // global variable
        function func() {
               alert(myname); // "undefined"
               var myname = "local";
               alert(myname); // "local"
        }
        func();

The first alert will say “undefined” because myname is considered declared as a local variable to the function. (Although the declaration comes after.) All the variable declarations get hoisted to the top of the function. Therefore to avoid this type of confusion, it’s best to declare upfront all variables you intend to use.

13)  Create efficient "for" loops: While iterating the Javascript collection in for loop, we should cache the length of collection in a variable and use that variable in for loop condition. E.g.

       for (var i = 0; i < myarray.length; i++) { //antipattern use of collection length
            // do something with myarray
       }

      //Right pattern
      var arrLength =  myarray.length;
      for (var i = 0; i < arrLength; i++) {
           // do something with myarray
      }

14)  Use hasOwnProperty(): It is important to use the method hasOwnProperty() when iterating over object properties to filter out properties that come down the prototype chain.E.g.

         var man = {hands: 2, legs: 2, head: 1};
         //somewhere else in the code
        // a method was added to all object
        If( typeof Object.prototype.clone === undefined){
                Object.prototype.clone = function(){};
        }

Somewhere before or after man was defined, the Object prototype was augmented with a
useful method called clone(). The prototype chain is live, which means all objects automatically get access to the new method. To avoid having the clone() method show up when enumerating man, you need to call hasOwnProperty() to filter out the prototype properties. E.g.

       // 1.
      // for-in loop
      for (var i in man) {
             if (man.hasOwnProperty(i)) { // filter
                    console.log(i, ":", man[i]);
             }
       }
       /*
          result in the console
          hands : 2, legs : 2, heads : 1
       */
       // 2.
      // antipattern:
     // for-in loop without checking hasOwnProperty()
      for (var i in man) {
           console.log(i, ":", man[i]);
      }
     /*
      result in the console
      hands : 2, legs : 2, heads : 1, clone: function()
    */

15)  Use “===” instead of “==”: JavaScript implicitly typecasts variables when you compare them. That’s why comparisons such as false == 0 or "" == 0 return true. To avoid confusion caused by the implied typecasting, always use the === and !== operators that check both the values and the type of the expressions you compare:

         var zero = 0;
         if (zero === false) {
               // not executing because zero is 0, not false
         }
         // antipattern
         if (zero == false) {
               // this block is executed...
         }

There’s another school of thought that subscribes to the opinion that it’s redundant to use === when == is sufficient. For example, when you use typeof you know it returns a string, so there’s no reason to use strict equality. However, JSLint requires strict equality; it does make the code look consistent and reduces the mental effort when reading code. (“Is this == intentional or an omission?”)

16)  Do not use Eval():Always remember the mantra that “eval() is Evil”.  This function takes an arbitrary string and execute it as javascript code.e.g.

         console.log(typeof un); // "undefined"
         var jsstring = "var un = 1; console.log(un);";
         eval(jsstring); // logs "1"
         console.log(typeof un); // "number"

So, here just by using eval we defined ‘un’ as a number literal. Suppose if the value of ‘jsstring’ is coming as an user input, how much security concern it may be. So, using eval() has security implications.

......To be continued in "Efficient coding style in ExtJs: Volume 3"

Very important links related to this post: