1. Introduction
From university to now, contact the front already has a few years, thoughts, even for programmers, want to improve their technical level and easy to read and maintain the code, I don’t feel I can write code that each day is a mediocre, more want to go to, to grope and optimize code, summary of skills, actively listening to the advice of others, In this way, their technical level will improve faster. So today, I am here just to share the practical skills of writing and the suggestion about javascript, these tips and Suggestions on development projects is my usual use, hope to be able to let everybody to learn knowledge, but also hopes to have the effect of an exchange views, that is to say you have any good tips or Suggestions, welcome to share. Or feel what problem exists in my idea, welcome to point out!
2. Shorter arrays to redo
[...new Set([2,"12", 2,12,1,2,1,6,12,13,6])] / [2,"12", 12, 1, 6, 13] // New es6 featuresCopy the code
3. Object depth copy
My personal opinion about deep and light copies of objects is the following:
1. Deep copy and shallow copy only apply to reference data such as Object and Array.
2. Shallow copy is to copy the reference address of the object without creating a new stack. That is, the result of the copy is that two objects point to the same reference address.
3. Deep copy is to open a new stack, two objects correspond to two different reference addresses, modify the properties of one object, does not change the properties of the other object.
Shallow copy
var myInfo={name:'wait',sex:'male'};
Copy the code
var newInfo=myInfo;
Copy the code
newInfo.sex='woman';
Copy the code
console.log(myInfo) //{name: "Waiting", sex: "Female"}
Copy the code
False – deep copy
False – deep copy of this is their own with the name of life, we look good, don’t take it seriously!
var myInfo={name:'wait',sex:'male'};Copy the code
var newInfo=Object.assign({},myInfo)Copy the code
newInfo.sex='woman';Copy the code
console.log(myInfo) //{name: "Waiting", sex: "Male"}
console.log(newInfo) //{name: "Waiting", sex: "Female"}
Copy the code
True – deep copy
True – deep copy of this is their own with the name of life, we look good, don’t take it seriously!
It’s easy to distinguish between the deep copy and the light copy, but the deep copy above is problematic. Look at the following example
Var arr = [{a: 1, b: 2}, {4} 3, a: b:] var newArr = Object. The assign ([], arr) newArr. / / truncation array length = 1. The console log (newArr) / / [{a: 1, b: 2}] Console. log(arr)//[{a:1,b:2},{a:3,b:4}] Console. log(arr[0])//{a: 123, b: 2}Copy the code
The reason for this is that object. assign is not a deep copy, but a shallow copy dressed up as a deep copy. At most, the Object. Assign class copies the values of the first layer, which are deep copies, and copy references to the second layer. Similar cases include slice and concat methods. To solve this problem, encapsulate the method yourself! The following
If the value of an Object property is a reference type (Array,Object), then the property is deeply copied until the value of the property is a primitive type.function deepClone(obj){
if(! obj&& typeof obj! = ='object') {return;
}
var newObj= obj.constructor === Array ? [] : {};
for(var key in obj){
if(obj[key]){
if(obj[key] && typeof obj[key] === 'object'){ newObj[key] = obj[key].constructor === Array ? [] : {}; // newObj[key] = deepClone(obj[key]); }else{ newObj[key] = obj[key]; }}}return newObj;
}
var arr=[{a:1,b:2},{a:3,b:4}]
var newArr=deepClone(arr)
console.log(arr[0])//{a:1,b:2}
newArr[0].a=123
console.log(arr[0])//{a:1,b:2}Copy the code
There is another method is simple and crude method, I am now using a method! The principle is simple: turn an object into a string, and then a string into an object! The same effect can be achieved
var newArr2=JSON.parse(JSON.stringify(arr));
console.log(arr[0])//{a:1,b:2}
newArr2[0].a=123
console.log(arr[0])//{a:1,b:2}Copy the code
The above shallow copy, true and false deep copy (with the name of their own life), these several situations, in development are likely to be used, as to which way to use, depending on the situation!
4. Use event delegates
A simple requirement, such as adding a click event to the LI under ul, is to display the innerHTML of that LI by clicking on it. This seems easy! The code is as follows!
<! DOCTYPE html> <html> <head> <meta charset="UTF-8">
<title></title>
</head>
<body>
<ul id="ul-test">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</body>
<script type="text/javascript">
var oUl=document.getElementById("ul-test");
var oLi=oUl.getElementsByTagName("li");
for(var i=0,len=oLi.length; i<len; i++){ oLi[i].addEventListener("click".function(){
alert(this.innerHTML)
})
}
</script>
</html>Copy the code
Very simple, this is achieved, in fact there is a pit, also need to optimize! 1. For loop, loop is li, loop 10 times, bind 10 events, 100 times loop, bind 100 events! 2. If li is not already on the page, it is a future element, the page is loaded, and then it is dynamically loaded through JS, the above writing method is invalid, click Li will not respond! So you need event delegates (even if you ignore the second case above, event delegates are recommended)! The following code
<! DOCTYPE html> <html> <head> <meta charset="UTF-8">
<title></title>
</head>
<body>
<ul id="ul-test">
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</body>
<script type="text/javascript">
var oUl=document.getElementById("ul-test");
oUl.addEventListener("click".function(ev){ var ev=ev||window.event; var target=ev.target||ev.srcElement; // If the bottom click is the li elementif(target.tagName.toLowerCase()==='li'){
alert(target.innerHTML)
}
})
</script>
</html>
Copy the code
The ul has only one event, and the event is bound to ul. No matter how many Li’s are added, the event is added once! If there is a child element below Li, then the target may not be Li, but the lowest element that the mouse clicks on. If you click on the white area, the target is the body element, click on the green area target is the div element, click on the blue area target is ul, and click on the orange area Target is Li.
5. Use objects as function arguments
Imagine a function that takes several arguments, but none of them are required. Is it like this?
functionpersonInfo(name,phone,card){ ... } // You can pass any parameter to the above function. Let's say I want to pass card is equal to 1472586326. I'm going to write personInfo(' '.' '.'1472586326')Copy the code
Do you find it strange and not very elegant? It looks better down here!
function personInfo(opt){
...
}
personInfo({card:'1472586326'})Copy the code
Think again, if a function has a lot of arguments, what do we do?
function test(arg1,arg2,arg3,arg4,arg5,arg6,arg7){
...
}Copy the code
Trypophobia relapse no relapse? It’ll make it look better down here!
function personInfo(opt){
...
}Copy the code
Finally, if the requirements change, so does the operation function! The function also takes an additional argument.
// The original functionfunctionpersonInfo(name,phone,card){ ... } // After modificationfunction personInfo(name,age,phone,card){
...
}Copy the code
This is a parameter modification, function parameters must be modified once! If you were using objects, you wouldn’t have this problem!
// This is the case before and after the modification, and becomes the operation content of the function and the call parameter!function personInfo(opt){
...
}Copy the code
In summary, when the parameters of the function are not fixed, the parameter is more (three or more than three), it is recommended to use an object to record the parameter, which will be more convenient, but also for the future if the parameter to change to leave a way back!
6. Merge arrays using push and apply
Merging arrays is an old topic, and there are many ways to merge arrays!
concat
Var arr1 = [1, 2, 3, 4, 5], arr2 =,7,8,9,10 [6]; arr1=arr1.concat(arr2) console.log(arr1)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Copy the code
Concat will create a new array representing the combination of arr1 and arR2, leaving arr1 and arR2 unchanged. Simple, right? But if both arr1 and ARR2 are long, then you have a very, very long array, and you’re using up that much memory. But the array length is unlimited!
for
Var arr1 = [1, 2, 3, 4, 5], arr2 =,7,8,9,10 [6];for(var i=0,len=arr2.length; i<len; i++){ arr1.push(arr2[i]) } console.log(arr1)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Copy the code
Here we add arR2 elements to the arR1 loop, but there is a case where the length of ARR1 is much smaller than the length of ARR2, is the loop ARR1 better performance, fewer cycles. That’s easy to handle, but what if you don’t know which one of these lengths is less, arr1 or arR2? Also, the for loop is not elegant! (Of course, this can be replaced by an iterative approach.)
reduce
Var arr1 = [1, 2, 3, 4, 5], arr2 =,7,8,9,10 [6]; arr1 = arr2.reduce(function(coll,item){
coll.push( item );
return coll;
}, arr1 );
console.log(arr1)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Copy the code
The bar is a bit higher, and using ES6’s arrow functions can reduce the amount of code, but it still requires a function that needs to be called once for each element.
push.apply
Var arr1 = [1, 2, 3, 4, 5], arr2 =,7,8,9,10 [6]; arr1.push.apply(arr1,arr2); console.log(arr1)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Copy the code
Push (arr1.push); push (arr1.push); push (arr1.push); push (arr1.push); The equivalent of arr1. Push. Apply (arr1,,7,8,9,10 [6]); , finally equivalent to arr1.push(6,7,8,9,10). Unfortunately, this method has a limit on the size of the array.
I suggested pushing. Apply before, but now I reserve my opinion, that is, we should use whichever way we think! There is no right or wrong way about this!
7. ToFixed keeps integers
In the development, often encounter the maximum number of decimal places to keep or similar problems, for this, using toFixed can be very simple to solve the problem, but if the data is to interact with the background, and the background storage of data is generally to save the number type, and after using toFixed generated is a string, this, ToFixed generates a string converted to a numeric type, forwarding a lot. Today I’m going to say the simplest one –+. The following code
Var a = 123.36896335. ToFixed (2) the console. The log (a) / /'123.37'A = + a console. The log (a) / / 123.37Copy the code
PS: a = a | 0 and ~ ~ a can be achieved, but the generated is an integer, is as follows
Var a = 123.36896335. ToFixed (2) the console. The log (a) / /'123.37'A = | 0 console. A log (a) / / 123 / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- line var a = 123.36896335 toFixed (2) the console. The log (a) / /'123.37'
a=~~a
console.log(a)//123
Copy the code
8. Transfer other types of data to Boolean data
The following transformation, we will understand at a glance, not to say.
console.log(!!'123') / /true!!!!! 12 / /true!!!!! 1 / /true!!!!! [] / /true!!!!!' '
//false!!!!! null //falseCopy the code
9. Cache variables
For loop cache length
Var arr = [6]for(var i=0,i<arr.length; i++){ ... } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - line var arr = [6]for(var i=0,len=arr.length; i<len; i++){ ... }Copy the code
The first paragraph is that each time the loop, the query arr.length. The second section of code is the cache arr. Length, every time the comparison of Len is good, in theory is the second section of code to write better, performance is relatively high! But as browsers evolve, the performance impact of this detail seems to be much smaller than expected, and caching is still recommended! I wrote the following test case (Google Chrome test)!
var arr100=[], arr10000=[];
for(var i=0; i<100; i++){ arr100.push(i) }for(var i=0; i<10000; I ++){arr10000.push(I)} // Cache conditionfunction testCache(arr){
console.time();
for(var i=0,len=arr.length; i<len; I++){} console.timeend ()} // no cachingfunction testNoCache(arr){
console.time();
for(var i=0,len=arr.length; i<len; i++){ } console.timeEnd() }testThe Cache (arr100) / / default: 0.007 mstestThe Cache (arr10000) / / default: 0.035 mstestNoCache (arr100) / / default: 0.012 mstestNoCache(ARR10000)//default: 0.109ms // This is just the simplest array, if traversing a nodeList (element list), the effect may be more obvious.Copy the code
Element event
Here I use jquery to explain, easier to understand, native JS is also the truth! The following code
$('.div1').click(function() {... }) //-------------------------- splitter var$div1= $('.div1');
$div1.click(function(){
...
})Copy the code
$div1 (‘.div1’); $div1 (‘.div1’);
10. Add elements using innerHTML
For example, if there is a requirement to add 10 Li to ul, there are two methods: the following code
<! DOCTYPE html> <html> <head> <meta charset="UTF-8">
<title></title>
</head>
<body>
<ul id="ul-test">
</ul>
</body>
<script type="text/javascript">
var oUl=document.getElementById("ul-test"); The console / / createElement method way. Time ();for(var i=0; i<10; i++){ var oLi=document.createElement('li'); oLi.innerHTML=i; oUl.appendChild(oLi); } console.timeEnd(); / / innerHTML way console. Time (); var _html=' ';
for(var i=0; i<10; i++){ _html+='<li>'+i+'</li>'
}
oUl.innerHTML=_html;
console.timeEnd();
</script>
</html>
Copy the code
When you open your code in a browser, you find that the second method is basically faster. As mentioned in point 8, DOM manipulation is as minimal as possible. The first one manipulates the DOM 10 times, the second one just once. Another one is, this is just a very simple one li, what about the following list? In the first way, how many times do we createElement, innerHTML, and appendChild? The code is much, the logic of each node and nesting relation is also disorderly! Using the second way is a concatenated string operation, better than the first way, if using es6 template string, it is simpler!
11. Convert the parameters into arrays
Arguments () has the length attribute, but arguments is not an array. There are no push,slice, etc methods. Sometimes, you need to convert arguments to an array. There is more than one way to convert arguments.
var _arguments=Array.prototype.slice.apply(arguments)
Copy the code
12. Function throttling
Said here take a chestnut, such as mousemove, onscroll, onresize when triggered, these events may have triggered the sixty events, it’s cost performance, and in fact, we don’t need so frequent trigger, as long as about 100 milliseconds to trigger a! So this requires function throttling!
longhand
var count = 0;
function beginCount() {
count++;
console.log(count);
}
document.onmousemove = function () {
beginCount();
};Copy the code
The effect
Throttling writing
var count = 0;
function beginCount() {
count++;
console.log(count);
}
function delayFn(method, thisArg) {
clearTimeout(method.props);
method.props = setTimeout(function () {
method.call(thisArg)
},100)
}
document.onmousemove = function () {
delayFn(beginCount)
};
Copy the code
The effect
This way, in fact, is a problem, in the continuous trigger stop to wait for 100ms to start executing, the middle operation is too fast directly ignore. Then find the following kind of plan on the net!
Second throttling notation
function delayFn2 (fn, delay, mustDelay){
var timer = null;
var t_start;
return function(){ var context = this, args = arguments, t_cur = +new Date(); // Clear the last call trigger (the last call trigger event is not executed) clearTimeout(timer); // If there is no trigger time, the current time is the trigger timeif(! t_start){ t_start = t_cur; } // Trigger the function once to run the function if the current time-trigger time is greater than the maximum interval (mustDelay)if(t_cur - t_start >= mustDelay){ fn.apply(context, args); t_start = t_cur; } // Otherwise, the execution is delayedelse {
timer = setTimeout(function(){ fn.apply(context, args); }, delay); }}; } var count=0;function fn1(){ count++; Console. log(count)} document.onmousemove=delayFn2(fn1,100,200)Copy the code
I now function throttling use very little, these two writing method is more basic, I hope you can share their own better method!
13. Other writing suggestions
Other writing tips and suggestions, such as naming conventions and the principle of function singleness, are fairly common. This part of the content of my own summary and others write the basic agreement! I’m not going to expand on that, so I recommend reading this article on how to write Elegant JavaScript code. Some of my knowledge came from here too!
14. Summary
Well, that’s it for some practical tips and advice I’ve picked up myself! For javascript tips and advice, you still need to read more resources on the Internet, but also to summarize their own, after all, MY own summary is only my own discovery, just the tip of the iceberg. But I still hope this article can help you, let you learn knowledge. Of course, more hope is to play a role of exchange of opinions. If you have any suggestions, tips. Welcome to share. You are also welcome to point out my mistakes and shortcomings. Let everyone help each other and learn from each other!
— — — — — — — — — — — — — — — — — — — — — — — — — gorgeous line — — — — — — — — — — — — — — — — — — — — want to know more, pay attention to focus on my WeChat public number: waiting for book cabinet