JavaScript is the most popular programming language in the world and can be used for web development, mobile application development (PhoneGap, Appcelerator), server-side development (Node.js and Wakanda), etc. JavaScript is also the first language for many novices to enter the world of programming. It can be used to display a simple prompt box in the browser, or to control the robot through nodebot or nodruino. Developers who can write JavaScript code with clear structure and high performance are now the most sought after people in the recruitment market.
In this article, I will share some JavaScript tips, secrets, and best practices that, with a few exceptions, apply to both the browser’s JavaScript engine and the server-side JavaScript interpreter.
The sample code in this article passed the test on the latest version of Google Chrome 30 (V8 3.20.17.15).
1. Be sure to use the var keyword when assigning a value to a variable for the first time
If a variable is assigned directly without being declared, it will be used as a new global variable by default. Try to avoid using global variables.
2. Use === instead of ==
The
== and != operators automatically convert data types if necessary. But === and !== don't, they compare values and data types at the same time, which also makes them faster than == and !=.
[10] === 10 // is false
[10] == 10 // is true
'10' == 10 // is true
'10' === 10 // is false
[] == 0 // is true
[] === 0 // is false
'' == false // is true but true == "a" is false
'' === false // is false
3. The logical results of underfined, null, 0, false, NaN, and empty string are all false
4. Use semicolon at the end of the line
In practice, it is best to use semicolons. It doesn’t matter if you forget to write them. In most cases, the JavaScript interpreter will add them automatically. For more information on why semicolons are used, please refer to the article The Truth About Semicolons in JavaScript.
5. Use object constructor
function Person(firstName, lastName){
This.firstName = firstName;
This.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");
6. Use typeof, instanceof and constructor carefully
typeof: JavaScript unary operator, used to return the original type of the variable in the form of a string. Note that typeof null will also return object. Most object types (array Array, time Date, etc.) will also return object
contructor: internal prototype property, can be overridden through code
instanceof: JavaScript operator, will search in the constructor in the prototype chain, and return true if found, otherwise return false
var arr = ["a", "b", "c"];
typeof arr; // Return "object"
arr instanceof Array // true
arr.constructor(); //[]
7. Use self-calling functions
The function is automatically executed directly after creation, usually called a self-invoked anonymous function (Self-Invoked Anonymous Function) or directly called function expression (Immediately Invoked Function Expression). The format is as follows:
(function(){
//The code placed here will be executed automatically
})();
(function(a,b){
var result = a b;
Return result;
})(10,20)
8. Randomly obtain members from the array
var items = [12, 548, 'a', 2, 5478, 'foo', 8852, , 'Doe', 2145, 119];
var randomItem = items[Math.floor(Math.random() * items.length)];
9. Get random numbers within the specified range
This function is particularly useful when generating fake data for testing, such as salaries within a specified range.
var x = Math.floor(Math.random() * (max - min 1)) min;
10. Generate a digital array from 0 to the specified value
var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i ) < max;); // numbers = [1,2,3 ... 100]
11. Generate random alphanumeric strings
function generateRandomAlphaNum(len) {
var rdmString = "";
for( ; rdmString.length < len; rdmString = Math.random().toString(36).substr(2));
Return rdmString.substr(0, len);
12. Disrupt the order of the number array
var numbers = [5, 458, 120, -215, 228, 400, 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* The numbers array will look like [120, 5, 228, -215, 400, 458, -85411, 122205] */
The built-in array sorting function of JavaScript is used here. A better way is to use specialized code to implement it (such as Fisher-Yates algorithm). You can see this discussion on StackOverFlow.
13. Remove spaces from strings
Java, C#, PHP and other languages all implement special string space removal functions, but there is no such function in JavaScript. You can use the following code to function a trim function for the String object:
String.prototype.trim = function(){return this.replace(/^s |s $/g, "");};
The new JavaScript engine already has a native implementation of trim().
14. Append between arrays
var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* The value of array1 is [12, "foo", {name "Joe"}, -2458, "Doe", 555, 100] */
15. Convert object to array
var argArray = Array.prototype.slice.call(arguments);
16. Verify whether it is a number
function isNumber(n){
Return !isNaN(parseFloat(n)) && isFinite(n);
}
17. Verify whether it is an array
function isArray(obj){
Return Object.prototype.toString.call(obj) === '[object Array]' ;
}
But if the toString() method is overridden, it won't work. You can also use the following method:
Array.isArray(obj); // its a new Array method
If frame is not used in the browser, instanceof can also be used, but if the context is too complex, errors may occur.
var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10]
// The constructor of myArray has been lost, and the result of instanceof will be abnormal
// The constructor cannot be shared across frames
arr instanceof Array; // false
18. Get the maximum and minimum values in the array
var numbers = [5, 458, 120, -215, 228, 400, 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);
19. Clear the array
var myArray = [12, 222, 1000];
myArray.length = 0; // myArray will be equal to [].
20. Do not delete or remove elements directly from the array
If you directly use delete on an array element, it is not deleted, but the element is set to undefined. Array element deletion should use splice.
Don’t:
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
delete items[3]; // return true
items.length; // return 11
/* The result of items is [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */
Instead:
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
items.splice(3,1) ;
items.length; // return 10
/* The result of items is [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119]
delete can be used when deleting the properties of an object.
21. Use the length attribute to truncate the array
In the previous example, the length attribute was used to clear the array. It can also be used to truncate the array:
var myArray = [12, 222, 1000, 124, 98, 10];
myArray.length = 4; // myArray will be equal to [12, 222, 1000, 124].
At the same time, if the length attribute is made larger, the length value of the array will increase, and undefined will be used as a new element to fill. length is a writable property.
myArray.length = 10; // the new array length is 10
myArray[myArray.length - 1]; // undefined
22. Use logical AND or in conditions
var foo = 10;
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();
Logical OR can also be used to set default values, such as default values for function parameters.
function doSomething(arg1){
arg1 = arg1 || 10; // arg1 will have 10 as a default value if it's not already set
}
23. Make the map() function method loop over the data
var squares = [1,2,3,4].map(function (val) {
Return val * val;
});
// squares will be equal to [1, 4, 9, 16]
24. Keep the specified number of decimal places
var num =2.443242342;
num = num.toFixed(4); // num will be equal to 2.4432
Note that toFixec() returns a string, not a number.
25. Problems with floating point calculation
0.1 0.2 === 0.3 // is false
9007199254740992 1 // is equal to 9007199254740992
9007199254740992 2 // is equal to 9007199254740994
Why? Because 0.1 0.2 is equal to 0.30000000000000004. Numbers in JavaScript are constructed in accordance with the IEEE 754 standard and are internally represented as 64-bit floating point decimals. For details, see how numbers in JavaScript are encoded.
This problem can be solved by using toFixed() and toPrecision().
26. Check the properties of the object through for-in loop
The following usage can prevent entering the object's prototype properties during iteration.
for (var name in object) {
If (object.hasOwnProperty(name)) {
// do something with name
}
}
27. Comma operator
var a = 0;
var b = ( a , 99 );
console.log(a); // a will be equal to 1
console.log(b); // b is equal to 99
28. Temporarily store variables used for calculation and query
In jQuery selectors, entire DOM elements can be temporarily stored.
var navright = document.querySelector('#right');
var navleft = document.querySelector('#left');
var navup = document.querySelector('#up');
var navdown = document.querySelector('#down');
29. Check the parameters passed to isFinite() in advance
isFinite(0/0); // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10); // true
isFinite(undefined); // false
isFinite(); // false
isFinite(null); // true, special attention should be paid to this
30. Avoid using negative numbers as indexes in arrays
var numbersArray = [1,2,3,4,5];
var from = numbersArray.indexOf("foo") ; // from is equal to -1
numbersArray.splice(from,2); // will return [5]
Note that the index parameter passed to splice should not be a negative number. If it is a negative number, the element will be deleted from the end of the array.
31. Use JSON to serialize and deserialize
var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* The result of stringFromPerson is "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}" */
var personFromString = JSON.parse(stringFromPerson);
/* The value of personFromString is the same as the person object */
32. Do not use eval() or function constructor
eval() and function constructor (Function consturctor) are relatively expensive. Every time they are called, the JavaScript engine must convert the source code into executable code.
var func1 = new Function(functionCode);
var func2 = eval(functionCode);
33. Avoid using with()
Using with() can add variables to the global scope. Therefore, if there are other variables with the same name, it will be easy to confuse, and the value will be overwritten.
34. Do not use for-in on arrays
Avoid:
var sum = 0;
for (var i in arrayNumbers) {
sum = arrayNumbers[i];
}
Instead:
var sum = 0;
for (var i = 0, len = arrayNumbers.length; i < len; i ) {
sum = arrayNumbers[i];
}
Another benefit is that the two variables i and len are in the first statement of the for loop, and they will only be initialized once, which is faster than the following way of writing:
for (var i = 0; i < arrayNumbers.length; i )
35. Use functions instead of strings when passing to setInterval() and setTimeout()
If you pass a string to setTimeout() and setInterval(), they will be converted in a similar way to eval, which will definitely be slower, so don’t use:
setInterval('doSomethingPeriodically()', 1000);
setTimeout('doSomethingAfterFiveSeconds()', 5000);
Instead use:
setInterval(doSomethingPeriodically, 1000);
setTimeout(doSomethingAfterFiveSeconds, 5000);
36. Use switch/case instead of a big stack of if/else
When judging that there are more than two branches, using switch/case is faster, more elegant, and more conducive to code organization. Of course, if there are more than 10 branches, do not use switch/case.
37. Use number intervals in switch/case
In fact, the case condition in switch/case can also be written like this:
function getCategory(age) {
var category = "";
switch (true) {
case isNaN(age):
category = "not an age";
break;
case (age >= 50):
category = "Old";
break;
case (age <= 20):
category = "Baby";
break;
default:
category = "Young";
break;
};
Return category;
}
getCategory(5); // will return "Baby"
38. Use objects as prototypes of objects
In this way, you can give an object as a parameter to create a new object based on this prototype:
function clone(object) {
Function OneShotConstructor(){};
OneShotConstructor.prototype = object;
Return new OneShotConstructor();
}
clone(Array).prototype; // []
39. HTML field conversion function
function escapeHTML(text) {
var replacements= {"<": "<", ">": ">","&": "&", """: """};
Return text.replace(/[<>&"]/g, function(character) {
return replacements[character];
});
}
40. Do not use try-catch-finally inside a loop
The catch part of try-catch-finally will assign the exception to a variable during execution, and this variable will be constructed into a new variable in the runtime scope.
Don’t:
var object = ['foo', 'bar'], i;
for (i = 0, len = object.length; i
Try {
// do something that throws an exception
}
catch (e) {
// handle exception
}
}
Instead:
var object = ['foo', 'bar'], i;
try {
for (i = 0, len = object.length; i
// do something that throws an exception
}
}
catch (e) {
// handle exception
}
41. Pay attention to setting timeout when using XMLHttpRequests
When XMLHttpRequests is executed, when there is no response for a long time (such as network problems, etc.), the connection should be terminated. This work can be completed through setTimeout():
Copy code The code is as follows:
var xhr = new XMLHttpRequest ();
xhr.onreadystatechange = function () {
If (this.readyState == 4) {
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
// do something with response data
}
}
var timeout = setTimeout( function () {
xhr.abort(); // call error callback
}, 60*1000 /* timeout after a minute */ );
xhr.open('GET', url, true);
xhr.send();
At the same time, it should be noted that do not initiate multiple XMLHttpRequests requests at the same time.
42. Handling WebSocket timeout
Normally, after a WebSocket connection is created, if there is no activity within 30 seconds, the server will timeout the connection. The firewall can also timeout the connection if there is no activity in the unit period.
In order to prevent this from happening, you can send an empty message to the server at certain intervals. This requirement can be achieved through the following two functions, one is used to keep the connection active, and the other is specifically used to end this state.
var timerID = 0;
function keepAlive() {
var timeout = 15000;
If (webSocket.readyState == webSocket.OPEN) {
webSocket.send('');
}
timerId = setTimeout(keepAlive, timeout);
}
function cancelKeepAlive() {
If (timerId) {
cancelTimeout(timerId);
}
}
The keepAlive() function can be placed at the end of the onOpen() method of the WebSocket connection, and cancelKeepAlive() is placed at the end of the onClose() method.
43. Please note that primitive operators are faster than function calls, use VanillaJS
For example, generally don’t do this:
var min = Math.min(a,b);
A.push(v);
It can be replaced by:
var min = a < b ? a : b;
A[A.length] = v;
44. Pay attention to the code structure when developing, and check and compress JavaScript code before going online
You can use tools like JSLint or JSMin to inspect and minify your code.