Original article address:13 most common JavaScript errors
1. For... array iteration usage of for... in to iterate Arrays
Example:
- var myArray = [ “a”, “b”, “c” ];
- var totalElements = myArray.length;
- for (var i = 0; i < totalElements; i++) {
- console.log(myArray[i]);
- }
The main problem here is that "for..." in the statement cannot guarantee the Order, which means you will get different execution results. In addition, if someone adds some other UDF array. prototype, your loop will traverse these functions repeatedly, just like the original array items.
Solution: always use the for loop of the rule to traverse the array.
- var myArray = [ “a”, “b”, “c” ];
- for (var i=0; i<myArray.length; i++) {
- console.log(myArray[i]);
- }
2. array dimension array dimensions
Example
- var myArray = new Array(10);
There are two different problems. First, the developer tries to create an array containing 10 items, which will create an array with 10 blank slots. However, if you try to get an array, you will get the result of "undefined. In other words, the effect is like you have no memory space to save. There is no real good reason to predefine the array length.
The second problem is that the developer uses the array constructor to create an array, which is technically correct, but is slower than the literal notation.
Solution: Use text symbols to initialize the array. Do not predefine the length of the array.
- var myArray = [];
3. undefined Properties
Example:
- var myObject = {
- someProperty: “value”,
- someOtherProperty: undefined
- }
The property is not defined. An element (Key 'someotherproperties' and value 'undefined') will be created in the object '.). If you traverse the array and check for existing elements, the following statements will return "undefined/undefined"
Typeof myobject ['someotherproperties'] // undefined
Typeof myobject ['unknownproperties'] // undefined
Solution: If you want to explicitly declare uninitialized attributes in the object, mark them as null ).
- var myObject = {
- someProperty: “value”,
- someOtherProperty: null
- }
4. Misuse of closures misuse of closures
Example:
- function(a, b, c) {
- var d = 10;
- var element = document.getElementById(‘myID’);
- element.onclick = (function(a, b, c, d) {
- return function() {
- alert (a + b + c + d);
- }
- })(a, b, c, d);
- }
Here, the developer uses two functions to pass parameters A, B, and C to onclick handler. Double functions are not required at all, increasing the complexity of the Code.
Variable ABC has been defined in local functions because they have been declared as parameters in the main function. Any function in a local function can create the closure of all variables defined in the main function. Therefore, you do not need to pass them again.
Solution: Use a closed loop to simplify your code.
- function (a, b, c) {
- var d = 10;
- var element = document.getElementById(‘myID’);
- element.onclick = function() {
- //a, b, and c come from the outer function arguments.
- //d come from the outer function variable declarations.
- //and all of them are in my closure
- alert (a + b + c + d);
- };
- }
5. closures in Loops
Example:
- var elements = document.getElementByTagName(‘div’);
- for (var i = 0; i<elements.length; i++) {
- elements[i].onclick = function() {
- alert(“Div number “ + i);
- }
- }
In this example, when users click different Divs, we want to trigger an action ("Div number 1", "Div Number 2 "... ). However, if you have 10 divs on the page, all of them will display "Div Number 10 ".
The problem is that when we use a local function to create a closure, the code in the function can access variable I. The key is that function I and function external I involve the same variables. When our loop ends, I points to the value 10, so the value of I in the local function will be 10.
Solution: Use the second function to pass the correct value.
- var elements = document.getElementsByTagName(‘div’);
- for (var i = 0; i<elements.length; i++) {
- elements[i].onclick = (function(idx) { //Outer function
- return function() { //Inner function
- alert(“Div number “ + idx);
- }
- })(i);
- }
6. DOM object internal test leakage memory leaks with DOM objects
Example:
- function attachEvents() {
- var element = document.getElementById(‘myID’);
- element.onclick = function() {
- alert(“Element clicked”);
- }
- };
- attachEvents();
This Code creates a reference loop. The variable element contains the reference of the function (To The onclick attribute ). At the same time, the function maintains a reference to the DOM element (prompting the function to access the element because of the closure .). Therefore, Javascript Garbage Collectors cannot clear elements or functions because they are referenced by each other. Most Javascript Engines are not smart enough to clear loop applications.
Solution: Avoid the closures or avoid circular references in the function.
- function attachEvents() {
- var element = document.getElementById(‘myID’);
- element.onclick = function() {
- //Remove element, so function can be collected by GC
- delete element;
- alert(“Element clicked”);
- }
- };
- attachEvents();
7. Differences between integer numbers and floating-point numbers differentiate float numbers from integer numbers
Example:
- var myNumber = 3.5;
- var myResult = 3.5 + 1.0; //We use .0 to keep the result as float
In JavaScript, there is no difference between floating point and integer. In fact, every number in Javascript indicates that the dual-precision 64-bit format IEEE 754 is used. In short, all numbers are floating points.
Solution: Do not use decimals to convert numbers (numbers) to floating points (floats ).
- var myNumber = 3.5;
- var myResult = 3.5 + 1; //Result is 4.5, as expected
8. Use with () as a shortcut usage of with () as a shortcut cut
Example:
- team.attackers.myWarrior = { attack: 1, speed: 3, magic: 5};
- with (team.attackers.myWarrior){
- console.log ( “Your warrior power is ” + (attack * speed));
- }
Before discussing with (), you must understand how JavaScript contexts works. Each function has an execution context (statement). In short, it includes all the variables that can be accessed by the function. Therefore, context contains arguments and definition variables.
What is with () actually? Is to insert an object to the context chain, which is embedded between the current context and the parent context. As you can see, the with () shortcut will be very slow.
Solution: Do not use with () for shortcuts. Only for context injection.
- team.attackers.myWarrior = { attack: 1, speed: 3, magic: 5};
- var sc = team.attackers.myWarrior;
- console.log(“Your warrior power is ” + (sc.attack * sc.speed));
9. setTimeout/setinterval string usage of strings with setTimeout/setinterval
Example:
- function log1() { console.log(document.location); }
- function log2(arg) { console.log(arg); }
- var myValue = “test”;
- setTimeout(“log1()”, 100);
- setTimeout(“log2(” + myValue + “)”, 200);
SetTimeout () and setinterval () can be either a function or a string as the first parameter. If you pass a string, the engine will create a new function (using the function constructor), which will be very slow in some browsers. Instead, the function itself is passed as the first parameter, which is faster, more powerful, and cleaner.
Solution: Do not use strings for setTimeout () or setinterval ().
- function log1() { console.log(document.location); }
- function log2(arg) { console.log(arg); }
- var myValue = “test”;
- setTimeout(log1, 100); //Reference to a function
- setTimeout(function(){ //Get arg value using closures
- log2(arg);
- }, 200);
10. setinterval () usage of setinterval () for heavy functions
Example:
- function domOperations() {
- //Heavy DOM operations, takes about 300ms
- }
- setInterval(domOperations, 200);
Setinterval () indicates that a function is included in the plan and executed only when no other execution is waiting in the main execution queue. The JavaScript engine only adds the next execution to the queue if no other execution is already in the queue. This may cause skipping or running two different executions without waiting for Ms between them.
Make sure that setinterval () does not consider how long it takes domoperations () to complete the task.
Solution: Avoid setinterval () and use setTimeout ()
- function domOperations() {
- //Heavy DOM operations, takes about 300ms
- //After all the job is done, set another timeout for 200 ms
- setTimeout(domOperations, 200);
- }
- setTimeout(domOperations, 200);
11. Misuse of "this" misuse of "this'
There are no examples of this common error because it is difficult to create it for demonstration. The value of this in Javascript is significantly different from that in other languages.
This value in a function is defined as the time when the function is called, rather than the declared time. This is very important. In the following example, this in a function has different meanings.
* Regular function: myfunction ('arg1 ');
This points to the global object, wich is window for all browers.
* Method: someobject. myfunction ('arg1 ');
This points to object before the dot, someobject in this case.
* Constructor: var something = new myfunction ('arg1 ');
This points to an empty object.
* Using call ()/apply (): myfunction. Call (someobject, 'arg1 ');
This points to the object passed as first argument.
12. Usage of eval () to access dynamic attributes usage of eval () to access Dynamic Properties
Example:
- var myObject = { p1: 1, p2: 2, p3: 3};
- var i = 2;
- var myResult = eval(‘myObject.p’+i);
The main problem is that using eval () to start a new execution statement is very slow.
Solution: Use square bracket notation instead of eval ().
- var myObject = { p1: 1, p2: 2, p3: 3};
- var i = 2;
- var myResult = myObject[“p”+i];
13. undefined as a variable usage of undefined as a variable
Example:
- if ( myVar === undefined ) {
- //Do something
- }
In the preceding example, undefined is actually a variable. All Javascript Engines will create the initialization Variable Window. undefined to undefined as the value. However, note that the variable is not only readable, but any other code can just change its value. It is strange to find that window. undefined has different values from undefined, but why is it risky?
Solution: Use typeof when checking for undefined items.
- if ( typeof myVar === “undefined” ) {
- //Do something
- }