JavaScript itself can be regarded as a simple language, but we are constantly improving it with wisdom and flexible patterns. Yesterday we applied these patterns to the JavaScript framework, and today these frameworks drive our web applications again. Many novice developers are attracted by various powerful JavaScript frameworks, but they ignore the practical JavaScript skills that are vast and vast behind the framework. This article will give you a comprehensive introduction to the knowledge points.
1. Operation of js integers
Use |0 and ~~ to convert floating point into integers and is faster than similar parseInt and Math.round, which will be useful when dealing with effects such as pixels and animation displacements. This is the performance comparison.
var foo = (12.4 / 4.13) | 0;//The result is 3var bar = ~~(12.4 / 4.13);//The result is 3
Another small trick is! ! 2 exclamation marks, you can talk about a value and quickly convert it into a boolean value. You can test it!
var eee="eee";alert(!!eee)
The return is true, which means that any value is preceded by it! ! All can be equal to true. Unless this value is originally a boolean value, or is undefined, null, 0, false, NaN, '', because the undefined, null, 0, false, NaN, '' mentioned, these are originally false, so two are added! ! After that, it's still fasle.
2. Rewrite the native alert and record the number of pop-up boxes
(function() { var oldAlert = window.alert, count = 0; window.alert = function(a) { count++; oldAlert(a + "/n You've called alert " + count + " times now. Stop, it's evil!"); };})();alert("Hello Haorooms");3. Methods of digital exchange not declaring intermediate variables
When exchanging two numbers, our general approach is to declare an intermediate variable, but today's approach is rather weird. You don't need to declare an intermediate variable and see how it is implemented!
var a=1,b=2;a=[b,b=a][0];console.log('a:'+a+',b:'+b); //Output a:2,b:1How about it, does this method have a new feeling?
4. Everything is an object
In the world of JavaScript, everything is an object. In addition to null and undefined, other basic types of numbers, strings and booleans have corresponding wrapper objects. One feature of an object is that you can call methods directly on it.
For numeric basic types, it will fail when trying to call the toString method on it, but it will not fail after being enclosed in brackets and then called. The internal implementation is to convert the basic type into an object with the corresponding wrapper object. So (1).toString() is equivalent to new Number(1).toString(). Therefore, you can indeed use basic types of numbers, strings, booleans, etc. as objects, just pay attention to the syntax to be appropriate.
At the same time, we noticed that numbers in JavaScript are not divided into floating point and shaping. All numbers are actually floating point types, just omitting the decimal point. For example, the 1 you see can be written as 1. This is why an error is reported when you try to 1. toString(), so the correct way to write it should be like this: 1..toString(), or add brackets as mentioned above. The purpose of brackets here is to correct the JS parser, and do not regard the point after 1 as a decimal point. The internal implementation is as mentioned above, converting 1. to an object with a wrapper object and then calling the method.
5. Deformation of If statement
When you need to write an if statement, try another easier method, using logical operators in JavaScript instead.
var day=(new Date).getDay()===0;//Traditional if statement if (day) { alert('Today is Sunday!');};//Use logic and replace ifday&&alert('Today is Sunday!');For example, the code above first gets today's date, if it is Sunday, pop-up window, otherwise nothing will be done. We know that there is a short circuit in logical operations. For logic and expressions, only if both are true can the result be true. If the previous day variable is judged to be false, then the result is false for the entire expression, so the subsequent alert will not be continued. If the previous day is true, the subsequent code must be continued to execute the following code to determine the authenticity of the entire expression. Using this point, the effect of if is achieved.
For traditional if statements, if the execution body code exceeds 1 statement, curly braces are required, and using comma expressions, any bar of code can be executed without curly braces.
if(conditoin) alert(1), alert(2), console.log(3);
6. Use ===, not ==
The == (or !=) operator will automatically perform type conversion when needed. The === (or !==) operation does not perform any conversion. It will compare values and types, and is also considered better than == in terms of speed.
[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
7. Use closures to implement private variables
function Person(name, age) { this.getName = function() { return name; }; this.setName = function(newName) { name = newName; }; this.getAge = function() { return age; }; this.setAge = function(newAge) { age = newAge; }; //Attributes that are not initialized in the constructor var occupation; this.getOccupation = function() { return occupation; }; this.setOccupation = function(newOcc) { occupation = newOcc; };}8. Create an object constructor
function Person(firstName, lastName){ this.firstName = firstName; this.lastName = lastName;}var Saad = new Person("Saad", "Mousliki");9. Be careful to use typeof, instanceof and constructor
var arr = ["a", "b", "c"];typeof arr; // return "object"arr instanceof Array // truearr.constructor(); //[]
10. Create a Self-calling Function
This is often called a self-Invoked Anonymous Function or an instant call function expression. This is a function that is automatically executed immediately after creation, usually as follows:
(function(){ // some private code that will be executed automatically})();(function(a,b){ var result = a+b; return result;})(10,20)11. Get a random item from the array
var items = [12, 548 , 'a' , 2, 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];var randomItem = items[Math.floor(Math.random() * items.length)];
12. Get a random number within a specific range
This snippet is very useful when you want to generate test data, such as a random salary value between the minimum and maximum values.
var x = Math.floor(Math.random() * (max - min + 1)) + min;
13. Generate an array of numbers between 0 and the set maximum value
var numbersArray = [] , max = 100;for( var i=1; numbersArray.push(i++) < max;); // numbers = [0,1,2,3 ... 100]
14. Generate a random number alphabetical string
function generateRandomAlphaNum(len) { var rdmstring = ""; for( ; rdmString.length < len; rdmString += Math.random().toString(36).substr(2)); return rdmString.substr(0, len);}//Call the method generateRandomAlphaNum(15);Fifteen. Scramble an array of numbers
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];numbers = numbers.sort(function(){ return Math.random() - 0.5});/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205] */16. String's trim function
String.prototype.trim = function(){return this.replace(/^/s+|/s+$/g, "");};17. Append (append) an array to another array
var array1 = [12 , "foo" , {name: "Joe"} , -2458];var array2 = ["Doe" , 555 , 100];Array.prototype.push.apply(array1, array2);/* array1 will be equal to [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */18. Convert arguments object into an array
var argArray = Array.prototype.slice.call(arguments); [Translator's note: The arguments object is an array object of class, but not a real array]
19. Verify whether the parameters are numbers (number)
function isNumber(n){ return !isNaN(parseFloat(n)) && isFinite(n);}20. Verify whether the parameters are arrays
function isArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ;}Note: If the toString() method is overridden, you will not get the desired result using this technique. Or you can use:
Array.isArray(obj); // This is a new array method
If you are not using multiple frames, you can also use the instanceof method. But if you have multiple contexts, you will get the wrong result.
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]// instance of will not work correctly, myArray loses his constructor// constructor is not shared between framesarr instance of Array; // false[Translator's note: There are many discussions on how to judge arrays on the Internet, you can google them. This article is written in detail. 】
21. Get the maximum or minimum value in an array of numbers
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);
[Translator's note: Here is a skill for passing parameters using the Function.prototype.apply method]
22. Clear an array
var myArray = [12 , 222 , 1000 ];myArray.length = 0; // myArray will be equal to [].
23. Do not use delete to delete items in an array.
Use splice instead of delete to delete an item in the array. Using delete just replaces the original item with undefined, not really deletes it from the array.
Don't use this method:
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];items.length; // return 11delete items[3]; // return trueitems.length; // return 11/* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */
And use:
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];items.length; // return 11items.splice(3,1) ;items.length; // return 10/* items will be equal to [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */
The delete method should be used to delete an object's property.
24. Use length to truncate an array
Similar to the way of clearing the array above, we use the length attribute to truncate an array.
var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].
In addition, if you set the length of an array to a larger value than the current one, the length of the array will be changed and a new undefined item will be added to fill it. The length of the array is not a read-only property.
myArray.length = 10; // the new array length is 10myArray[myArray.length - 1] ; // undefined
25. Use logical AND/OR to make conditional judgments
Same (five), if deformation statement!
var foo = 10;foo == 10 && doSomething(); // is equivalent to if (foo == 10) doSomething();foo == 5 || doSomething(); // is equivalent to if (foo != 5) doSomething();
Logical AND can also be used to set default values for function parameters
function doSomething(arg1){ Arg1 = arg1 || 10; // If arg1 is not set, Arg1 will be set to 10 by default}26. Use map() method to traverse items in an array
var squares = [1,2,3,4].map(function (val) { return val * val;});// squares will be equal to [1, 4, 9, 16]27. Round a number and retain N decimal places
var num =2.443242342;num = num.toFixed(4); // num will be equal to 2.4432
28. Floating point number problem
0.1 + 0.2 === 0.3 // is false9007199254740992 + 1 // is equal to 90071992547409929007199254740992 + 2 // is equal to 9007199254740994
Why is this happening? 0.1+0.2 equals 0.3000000000000000000004. You should know that all JavaScript numbers are internally floating-point numbers expressed in 64-bit binary, complying with the IEEE 754 standard. For more information, you can read this blog post. You can use toFixed() and toPrecision() methods to solve this problem.
29. When using for-in to traverse the internal properties of an object, please check the properties.
The following code snippet can avoid accessing the properties of the prototype when traversing an object property.
for (var name in object) { if (object.hasOwnProperty(name)) { // do something with name }}Thirty, comma operator
var a = 0;var b = ( a++, 99 );console.log(a); // a will be equal to 1console.log(b); // b is equal to 99
31. Cache variables that need to be calculated and queryed (calculation or querying)
For jQuery selectors, we'd better cache these DOM elements.
var navright = document.querySelector('#right');var navleft = document.querySelector('#left');var navup = document.querySelector('#up');var navdown = document.querySelector('#down');var navdown = document.querySelector('#down');32. Verify the parameters before calling isFinite()
isFinite(0/0) ; // falseisFinite("foo"); // falseisFinite("10"); // trueisFinite(10); // trueisFinite(undifined); // falseisFinite(); // falseisFinite(null); // true !!!33. Avoid negative indexes in arrays
var numbersArray = [1,2,3,4,5];var from = numbersArray.indexOf("foo") ; // from is equal to -1numbersArray.splice(from,2); // will return [5]Make sure that the parameters when invoking indexOf are not negative.
34. Serialization and deserialization based on JSON
var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };var stringFromPerson = JSON.stringify(person);/* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}" */var personFromString = JSON.parse(stringFromPerson);/* personFromString is equal to person object */35. Avoid using eval() and Function constructors
Using eval and Function constructors is very expensive because every time they call the script engine to convert the source code into executable code.
var func1 = new Function(functionCode); var func2 = eval(functionCode);
36. Avoid using with()
Using with() will insert a global variable. Therefore, variables with the same name will be overwritten and cause unnecessary trouble.
37. Avoid using for-in to traverse an array
Avoid using this method:
var sum = 0;for (var i in arrayNumbers) { sum += arrayNumbers[i];}A better way is:
var sum = 0;for (var i = 0, len = arrayNumbers.length; i < len; i++) { sum += arrayNumbers[i];}The additional benefit is that the values of both i and len variables are executed only once, which will be more efficient than the following method:
for (var i = 0; i < arrayNumbers.length; i++)
Why? Because arrayNumbers.length is calculated every time the loop is looped.
38. Pass the function instead of a string when calling setTimeout() and setInterval().
If you pass a string to setTimeout() or setInterval(), the string will be parsed as if it were used with eval, which is very time-consuming.
Do not use:
setInterval('doSomethingPeriodically()', 1000);setTimeOut('doSomethingAfterFiveSeconds()', 5000)And use:
setInterval(doSomethingPeriodically, 1000); setTimeOut(doSomethingAfterFiveSeconds, 5000);
39. Use switch/case statements instead of a long list of if/else
When judging that the situation is greater than 2, using switch/case is more efficient and more elegant (easier to organize the code). But do not use switch/case when there are more than 10 judgments.
40. Use switch/case when judging the numerical range
In the following situation, it is reasonable to use switch/case to determine the numerical range:
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"[Translator's Note: Generally speaking, if/else will be more appropriate to judge the numerical range. switch/case is more suitable for judgment of determining the value]
41. Specify a prototype object for the created object
It is possible to write a function to create an object that specifies parameters as prototype:
function clone(object) { function OneShotConstructor(){}; OneShotConstructor.prototype= object; return new OneShotConstructor();}clone(Array).prototype ; // []42. An HTML escape function
function escapeHTML(text) { var replacements= {"<": "<", ">": ">","&": "&", "/"": """}; return text.replace(/[<>&"]/g, function(character) { return replacements[character]; });}43. Avoid using try-catch-finally inside a loop
At runtime, each time the catch clause is executed, the captured exception object will be assigned to a variable, and in the try-catch-finally structure, this variable will be created every time.
Avoid writing this way:
var object = ['foo', 'bar'], i;for (i = 0, len = object.length; i <len; i++) { try { // do something that throws an exception } catch (e) { // handle exception }}And use:
var object = ['foo', 'bar'], i;try { for (i = 0, len = object.length; i <len; i++) { // do something that throws an exception }}catch (e) { // handle exception}44. Set a timeout for XMLHttpRequests.
After an XHR request takes up a long time (for example, due to network problems), you may need to abort the request, so you can use setTimeout() for the XHR call.
var xhr = new XMLHttpRequest ();xhr.onreadystatechange = function () { if (this.readyState == 4) { clearTimeout(timeout); // 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();In addition, generally you should avoid synchronized Ajax requests altogether.
Forty-five. Handle WebSocket timeout
Usually, after a WebSocket connection is created, if you are not active, the server will disconnect (time out) your connection after 30 seconds. The firewall will also be disconnected after a period of inactivity.
To prevent timeout issues, you may need to send empty messages to the server side intermittently. To do this, you can add the following two functions in your code: one to keep the connection and the other to unretain the connection. With this trick, you can control the timeout problem.
Use a timerID:
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() method should be added at the end of the onOpen() method of the webSOcket connection, and cancelKeepAlive() is added at the end of the onClose() method.
46. Remember that original operators are always more efficient than function calls. Use VanillaJS.
For example, do not use:
var min = Math.min(a,b);A.push(v);
And use:
var min = a < b ? ab;A[A.length] = v;
47. From integers, randomly select a value
There is the following formula, which is very useful, and allows us to randomly display certain famous quotes or news events!
Value = Math.floor(Math.random() *Total number of possible values + first possible value)
For example: To select a value between 2 and 10, we can write it like this
var num=Math.floor(Math.random()*9+2)
Please remember the above formula! ~
The usage and function of the single vertical bar of the js operator "|" and the processing of js data
Just now, when operating js integers, it is equivalent to removing the decimal point, parseInt. When a positive number is equivalent to Math.floor(), and when a negative number is equivalent to Math.ceil() Note:
1. Math.ceil() is used as upward rounding. 2. Math.floor() is used as rounding downwards. 3. Math.round() Round() commonly used in mathematics. console.log(0.6|0)//0console.log(1.1|0)//1console.log(3.65555|0)//3console.log(5.99999|0)//5console.log(-7.777|0)//-7
Note: In addition to the three methods of Math to process numbers, we often use parseInt(), parseFloat(), toFixed() and toPrecision(), etc. A brief explanation:
The usage of the toFixed method is as follows:
100.456001.toFixed(2); //100.47100.456001.toFixed(3); //100.456Number.prototype.toFixed.call(100.456001,2); //100.47
Disadvantages: After use, it will become a string.
ToPrecision usage is as follows:
99.456001.toPrecision(5); //99.456100.456001.toPrecision(5); //100.46Number.prototype.toPrecision.call(10.456001,5); //10.456
Operation rules for single vertical bars
After looking at the above example, we generally know that a single vertical bar can perform rounding operation, which means that only the positive part is retained and the decimal part is removed. However, how does "|0" be calculated? Why can "|0" achieve the purpose of rounding? What will be the single vertical bar be if it is not 0?
With these questions in mind, let's look at the following example:
console.log(3|4); //7console.log(4|4); //4console.log(8|3); //11console.log(5.3|4.1); //5console.log(9|3455); //3455
It seems that there is no pattern to find? Search online. http://tools.VeVB.COM/table/priority
This mentions a single vertical bar "|" but there is no JavaScript.
OK, I'll announce the answer here. In fact, the single vertical bar "|" is the result obtained by converting it to 2-digit system. For example, let’s take a simple example:
3|4 is converted to binary and 011|100 Addition gives 111=74|4 is converted to binary and 100|100 Addition gives 100=48|3 is converted to binary and 1000|011 Addition gives 1011=11
And so on, I won't list them one by one here. The single vertical bar "|" operation is the result obtained by converting it to 2-digit system! Have you learned it all?