JavaScript Recipes: A Problem-Solution Article

Why reinvent the wheel every time you run into a problem with JS? This article is chock-full of code recipes that address common programming tasks.

Q: What is Javascript object creation best practice?

How to protect themselves from errors, if the new keyword is used? I always capitalize constructor names. I use this instanceof funcName to validate the instance, and avoid this instanceof arguments.callee due to performance reasons.

A:

It is definitely a good practice to create objects with help of the new keyword. It is common convention: constructor functions have names that start with capital letters. The fact that constructor invocation is different from regular function invocation is another reason we give constructors names start with capital letters. Constructors are created to be invoked as constructors, with the new keyword. Constructors will not work properly, if they are invoked as a regular functions.

The new keyword must not be used for factory methods and short jQuery constructors:

Q: How to determine which mouse button is clicked?

A:

All the buttons call the mousedown mouseup events. Only left mouse button calls the clickevent. In the event handler, you must check the button code event.button to determine which one has been clicked. (0 — Left, 1 — Middle, 2 — Right). But do not forget about IE8 where it doesn’t work.

jQuery fixes this problem. You need to check event.which instead event.button

Here is a jsfiddle example.

For more details please read the Which mouse button has been clicked? paragraph.

jQuery event.which: api.jquery.com/event.which/

Q: How to catch keystroke events?

Example: I have a table that is larger the screen size. I need to navigate between rows with the help of keyboard arrows. How to forbid the browser scrolling the window while navigating the table?

A:

To do so, you need to disable the default action. You can use jQuery:

There is an important point. You must perform the preventDefault() before the defaultAction is executed. For example, you do not want to pass the focus to the input while clicking it — then you need to add the event handler to the event in the chain, before the mousedown defaultAction :

The event chain looks as follows:

1. mousedown
2. focus (before focus, the blur is invoked for another object)
3. mouseup
4. click

If you add an event for focus or “below”, nothing will work, because defaultAction will be executed after mousedown.

Q: How to stop GIF animation by pressing ESC when the button is binded?

A:

The answer is similar to one listed above. While pressing ESC, some browsers stop GIF animation and stop page loading. It is default behaviour. You need to disable the default behaviour with event.preventDefault():

Q: What is the ( ) operator?

A:

Parser determines what kind of parentheses goes after a function: grouping or the function call operator. If we do like this:

We will get a syntax error, because we do not have a function name. Function declaration must always have a name! If we add a name:

We suppose that everything is OK as far as we already have a name. However, we still have an error. This time we have a grouping operator without an expression inside. Note, this time it is the grouping operator that follows after function declaration and not parentheses for function call.
There are several ways to avoid parsing errors:

You may find this approach in jQuery. This allows you to separate all the code in one block with local scope. It doesn’t clutter up the global namespace and allows minifiers better compress the code. This also speeds up access to internal variables.
For more details read here: Named function expressions demystified

Q: How to organize the commands execution queue with a delay and no script hangup?

A:

JavaScript has one thread. Whenever you perform a chain of operations (cycles or heavy functions) the user interaction with the UI is blocked. Web workers help to prevent UI blocking. If there is no possibility to use web workers, you need to perform the optimization of cycles and “heavy” functions.
Nicholas C. Zakas stated — If the interface responds to user input within 100 ms, the user thinks that he is “directly manipulating the objects in the user interface.” Any amount of time more than 100 ms means the user feels disconnected from the interface. Since the UI cannot update while JavaScript is executing, the user cannot feel in control of the interface if that execution takes longer than 100 ms.

The following code is optimized:

The timedProcessArray function blocks UI for 25 ms, executes a chain of actions and then releases UI for another 25 ms and so on.

Q: How to determine that a user is finished resizing the window?

A:

There is no event for this case. However, you can get the information about when the user resized the window last time?

Q: How to open a new window (not a tab) with the help of window.open()?

A:

This behavior depends on the browser. Opera always opens a tab and it is represented as a window, Safari always opens a window, Chrome, Firefox, and IE are manageable.

If you pass additional parameters — the position of the window, a new window opens:

If you do not pass it, a new tab opens:

More often a new tab is required. In this case, you may have some troubles with Safari. By default (depending on settings) it opens a new window. However, while clicking a link and holding Ctrl+Shift/Meta+Shift it opens a new tab regardless the settings.To open a new tab you need to emulate a mouse click when Ctrl+Shift/Meta+Shift are hold.

Q: What is the best way to clone/deep copy?

A:

If an oldObject is not going to be changed, the most efficient way is to use the prototype:

If you need a true cloning, it is better recursively go through the object tree:

For jQuery:

Q: How to create a destructor/finalizer analogue? How to manage object lifetime?

A:

In JavaScript, the object is deleted when there are no references to this object.

You can not delete the object entirely by using a destructor. You can only clean its content.

Q: How to process binary data?

A:

In JavaScript all numbers are provided for use in the string format. There are no built-in tools to work with binary data. However, there is the JavaScript BinaryParser library to work with binary data. Its code is a nightmare!

ECMAScript 6 + (strawman) contains the StructType draft (like struct in C++). Here’s how it might look in the future:

You can use JavaScript typed arrays to read from buffers, however, you will not be able to get a number in binary format.

Q: How to change function context variables from another function?

A:

1. You can pass a reference to the primer context object in smth.
2. You can pass a function created in the primer context into the smth function.

Q:  How to pass execution scope from one function to another?

A:

There’s no way! There was the possibility to use __parent__ in FireFox 3.6. In v.4 they have thrown this feature.

Q: How to get a global object without explicit pointing, without eval and with ‘use strict’?

A:

There’s no way! If we omit one of the conditions or use the global scope:

Q: I have Intercepted a javascript event, can I restart it later?

A:

You can explicitly pass a reference to an event handler:

Unfortunately, it is not a good solution. It is better to change the logic and separate the handler:

Q: How to intercept all clicks on the page?

A:

You need to add an event handler to the click event to the “last/lowest” element in the DOM tree.

Q: How to execute XHR without jQuery?

A:

Not a cross-browser function:

A cross-browser function is little bit longer:

How to use:

If you have something to add, please drop a comment below! Thank you!

Andrey Langovoy

Andrey Langovoy

Andrey Langovoy is a team leader at Devart. He takes part in development and testing database management tools for SQL Server, writes articles about SQL Server and contributes to open source projects, MSDN and MDN.
Andrey Langovoy

Latest posts by Andrey Langovoy (see all)

Andrey Langovoy

Andrey Langovoy is a team leader at Devart. He takes part in development and testing database management tools for SQL Server, writes articles about SQL Server and contributes to open source projects, MSDN and MDN.