About for-in Loops
When looping data, it is strongly deprecated to use the for-in loop. Because when the array object is expanded, iterating through the data with the for-in loop can cause a logical error, for example:
var arr = [‘a’, ‘b’, ‘c’];
// subscript traversal
for (var i = 0, len = arr.length; i <len; i ++) {
console.info (typeof i); // number
console.info (i);
}
// for-in traversal
for (var i in arr) {
console.info (typeof i); // string
console.info (i);
}
console.log (arr.length); // 3
At this point, when for-in iterates through the array, I is of type string, no longer an array subscript, but as a key to the array object (an array in JavaScript is also an object).
If you add the following code before the traversal, the for-in loop will have a logical error
if(typeof Array.prototype.len === ‘undefined‘) {
Array.prototype.len = function() { return this.length;
};
}
That is, add a prototype method to the array len ()
Console.log (arr.length); Output is still 3
The for-in loop, however, outputs Len at the same time, which means that for-in is actually traversing the array as an object, and Len is naturally traversed as a property of the objects.
In short, we can not mess with the prototype to add methods, can not guarantee that others will not, so it is best not to use the for-in loop array.
When using for-in to traverse an object, typically used with hasOwnProperty (), hasOwnProperty () is used to filter the prototype properties or prototype methods, for example:
// define a person object, containing two properties and a method
var person = {
name: ‘Zhang San’,
age: 28,
say: function () {
// ...
}
}
// extend a method sleep () on Object
if (typeof Object.prototype.sleep === ‘undefined’) {
Object.prototype.sleep = function () {
// ...
}
}
// use for-in loop of hasOwnProperty ()
for (var i in person) {
if (person.hasOwnProperty (i)) {
console.info (i);
}
}
/ *
The console prints the results:
name
age
say
* /
// do not use for-in loop of hasOwnProperty ()
for (var i in person) {
console.info (i);
}
/ *
The console prints the results:
name
age
say
sleep
* /
It should be explained that not using hasOwnProperty () is not wrong, but it may cause some confusion in the loop results, if your code has enough confidence, can not hawownproperty (), but also slightly improve the cycle speed.
Do not add built-in prototypes
Adding a method or attribute to a built-in prototype is a powerful feature, but because of its power, it often brings huge costs to maintenance. In addition, as mentioned above, if the built-in prototypes are extended, there will be some confusion in loops that do not use hasOwnProperty ().
If you must extend the prototype, check to see if the custom property or method already exists, and if it does not exist then expand it, and be sure to document it in order for the team to communicate. The following patterns can be used to extend the prototype:
if(typeof Object.prototype.myMethod === ‘undefined‘) {
Object.prototype.myMethod = function() { // ... }
}
Avoid the use of hidden type conversions
JavaScript has a hidden type conversion, such as Fasle = = 0, "" = = 0 This kind of comparison statements return true, to some extent will cause confusion, type unclear.
It is recommended to compare values and types in comparison statements using = = = and!==
Avoid using eval ()
The first sentence, "eval () is the devil"
Generally written code is not required to use eval (), if the code is generated dynamically during the run process, you may need to use eval () to convert it to JavaScript code, but there is a better way to replace the eval (), this kind of situation most appear in the processing of the Ajax return value, such as :
// The ajax request returns a string "name", to add an attribute to an object obj, and use name as the attribute name, ‘张三’ as the attribute value
var property = "name";
var obj = {
age: 22
};
// anti-pattern, do not use
// eval (‘obj.‘ + property + ‘=" z3 "');
// recommended
obj [property] = ‘Zhang San’;
for (var i in obj) {
console.info (i);
}
Using eval () also contains some pitfalls, and it is possible to execute some code that has been tampered with.
Also, the call to SetInterval () and settimeout () has a similar problem with eval ()
// anti-pattern
setTimeout (“myFunc ()”, 1000);
setTimeout (“myFunc (2, 5, 7)”, 1000);
// recommended
setTimeout (myFunc, 1000);
setTimeout (function () {
myFunc (2, 5, 7);
}, 1000);
If you must use Eval (), consider whether you can use the new Function () instead of Eval ().
Because using the new function () code will run in a local function space, any variable defined with VAR will not automatically become a global variable, for example:
new Function("var p = 3; console.info(p);")(); // 3
console.info(p); // ReferenceError: p is not defined
eval("var p1 = 4; console.info(p1);"); // 4
console.info(p1); // 4
Another way to prevent auto-becoming a global variable is to enclose eval () in an immediate execution function, such as:
(function(){
eval(‘var num = 11; console.info(num);‘); // 11
})();
console.info(num); // ReferenceError: p is not defined
Another difference between the new function () and eval () is that eval () affects the scope chain, and the new function () has less impact on local variables.
Eval () can access and modify the variables of its outer scope, and new function () cannot. Example:
(function(){
var num = 13;
eval(‘var num = 20; console.info(num);‘); // 20
console.info(num); //20, 改变了num的值
})();
(function(){
var num = 12;
new Function(‘var num = 17; console.info(num);‘)(); // 17
console.info(num); // 12
})();
Use the numerical conventions of parseint ()
This Convention is mainly to solve the problem of ECMAScript old and new version inconsistency,
In earlier versions of ECMAScript, a string starting with 0 would be treated as an octal number and changed in ECMAScript5, so it is best not to ignore the second parameter (the binary parameter) when using the parseint () method.
For example, when working with a date string:
var month = ‘07‘,
date = ‘02‘;
month = parseInt(month, 10);
date = parseInt(date, 10);
In addition, if you are converting a pure numeric string, such as ' 09 ', then using number (' 09 ') will be more efficient,
If it is a non-pure numeric string, such as ' parseint ', then only the use of the (' *. Hello ') will be used, and number (' Hello ') returns Nan
Coding conventions
The coding conventions mentioned in the book are designed to improve the readability of the code and reduce the maintenance cost of the code.
Include indentation, space, curly braces, naming conventions, use of spaces, and so on.
One of the things to note is the position of the curly braces, which can cause some code execution to be unexpected due to the insertion mechanism of the semicolon, for example:
// anti-pattern
setTimeout (“myFunc ()”, 1000);
setTimeout (“myFunc (2, 5, 7)”, 1000);
// recommended
setTimeout (myFunc, 1000);
setTimeout (function () {
myFunc (2, 5, 7);
}, 1000);
<<javascript patterns>> Reading Notes-2nd Chapter Basic Skills (II.)