📜 ⬆️ ⬇️

ES5 JavaScript Guide


Javascript quality guide


With the help of the tips suggested in this guide, you will write code that is understandable to any development team.

From translator


Hello everyone, Maxim Ivanov with you, and today we will talk about the rules for formatting the code in JavaScript . Nicolas Bevacqua , author of JavaScript Application Design, developer from Argentina, published this guide a long time ago, the first entry appeared in 2014, much is written according to the ES5 standard, however, these days it is all the same true now, when ES6 is still nowhere fully working without babel and other transpilers. Although we are seeing progress in top desktop browsers (Google Crhome, Firefox), where 70-90% of the plans have already been implemented, we see that they are striving to maintain the new standard, but unfortunately, there are still no browsers that could fully support ES6 . By the way, I will be very glad to your comments. In general, good luck and let's get started.


Introduction


These recommendations are not carved in stone, these are basic rules that will help you learn how to write more consistent and understandable code. To effectively apply the proposed rules in practice, start right now, share them with your colleagues and introduce them into production. However, do not dwell on these rules, it can be fruitless and counterproductive. Try to find a middle ground to make everyone comfortable in your team. Automated checking of code style is quite a useful thing, since the style of writing code is everyone’s business.
')

Content


  1. Modules
  2. Strict regime
  3. Formatting spaces
  4. Semicolon
  5. Code style
  6. Error code analysis
  7. Strings
  8. Variable initialization
  9. Conditional constructions
  10. Comparisons
  11. Ternary operator
  12. Functions
  13. Prototypes and Inheritance
  14. Objects
  15. Arrays
  16. Regular expressions
  17. Developer Console
  18. Comments
  19. Naming
  20. Polyfill library
  21. Daily Tricks
  22. ES6 Guide


Modules


This item assumes that you are using modular systems such as CommonJS, AMD, ES6 Modules, or any other. Modular systems work with a separate scope, without affecting global objects, they also provide a more organized code structure by automatically generating dependencies, freeing you from inserting the <script> tag yourself.

Modular systems can load templates, which in turn are useful for local solutions when it comes to testing a separate isolated component.

To read :

1. What is a module?
2. CommonJS Modules
3. Modules in JS

Strict regime


Always use 'use strict'; at the top of your module. Strict mode allows you to catch the errors of the language, although it is a bit scary name, this mode allows the interpreter to monitor the quality of your code, thus you spend less time correcting errors.

To read

1. Use strict directive
2. Strict Mode

Formatting spaces


Control the number of spaces when formatting a code. For this, it is recommended to use the .editorconfig configuration file . I suggest using these settings.

# editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false 


Using tabs and spaces is your own business, but I recommend two spaces to indent. The .editorconfig file takes care of everything, the formatting process will also be monitored when you press the Tab key.

You can customize not only the correct tab, you can also adjust the indentation in the right places, for example, before, after or between something. True to perform control over such things is quite a laborious task.

 function () {} function( a, b ){} function(a, b) {} function (a,b) {} 

Try to minimize the differences in the formatting of your code.

Where possible, improve the readability of the code, try to write a maximum of 80 characters in one line.

To read:

1. EditorConfig
2. One settings for all editors
3. Install EditorConfig in Sublime text 3
4. 80-characters
5. Good programming style

Semicolon


Most JavaScript programmers prefer to use a semicolon . The semicolon must always be set in order to avoid automatic substitution (ASI). There are languages ​​in which the semicolon is optional, and nobody puts it there. In JavaScript, the newline replaces it, but only partially, so it’s better to put it if you understand the ASI rules.

Regardless of the fact that you are sure of your code, use the validator (linter) to catch unnecessary semicolons.

To read:

1. JavaScript Semicolon Insertion
2. Code Style Tips
3. Improving the quality of javascript code
4. Everything you need to know about the semicolon
5. An open letter to JS leaders regarding semicolons

Code style


You should not bother with this, because this is an extremely painful and tense moment, which does not bring any noticeable success if you follow the same strict policy in other areas.

Of course, a certain code design standard (programming style) (English coding convention) exists. In the JavaScript world, there are even tools to check your code for compliance with this standard - JSCS (JavaScript Code Style). Having a common programming style makes it easier to understand and maintain source code written by more than one programmer, and also simplifies the interaction of several people when developing software.

These standards come as programmers and the best teams, as well as entire companies:
1. Airbnb
2. Douglas Crockford
3. Google
4. Grunt
5. Idiomatic
6. jQuery
7. MDCS
8. Node.js
9. Wikimedia
10. WordPress
11. Yandex

To read:

1. Programming style
2. JavaScript Code Style

Error code analysis


On the other hand, validation is sometimes necessary. If you are not using a validator, then you are exactly sure how your code works, and you do not need to use, for example, JSLint (software quality control tool). And yet, I recommend using JSHint or ESLint.

A few tips in using JSHint:


 { "curly": true, "eqeqeq": true, "newcap": true, "noarg": true, "noempty": true, "nonew": true, "sub": true, "undef": true, "unused": true, "trailing": true, "boss": true, "eqnull": true, "strict": true, "immed": true, "expr": true, "latedef": "nofunc", "quotmark": "single", "indent": 2, "node": true } 


Of course, you are not obliged to strictly adhere to these rules, but it is important to find a middle ground between the validator and other programming styles.

To read:

1. JSLint
2. JSHint
3. A few tips on setting up ESlint
4. Configure JSHint in sublime text 3
5. JavaScript lintting

Strings


All strings must have the same type of quotes. Use single or double quotes throughout the code.
 //  var message = 'oh hai ' + name + "!"; 

 //  var message = 'oh hai ' + name + '!'; 

This will work faster if you use a formatting function similar to that of util.format in Node.js. Thus, it will be easier for you to format the lines, and the code will look much cleaner.

 //  var message = util.format('oh hai %s!', name); 

You can implement something like this by using the code below.
 function format () { var args = [].slice.call(arguments); var initial = args.shift(); function replacer (text, replacement) { return text.replace('%s', replacement); } return args.reduce(replacer, initial); } 

To declare multiline (multiline), especially when it comes to HTML snippets, it is sometimes better to use an array as a data buffer, the elements of which can later be merged into a string. Of course, concatenating (merging) strings is much easier in the familiar style and, of course, it will work faster, but sometimes it is more difficult to track.
 var html = [ '<div>', format('<span class="monster">%s</span>', name), '</div>' ].join(''); 

You can insert your snippets into the array to be merged and at the end merge them to better read the code. This is how some template engines work, such as Jade.

To read:

1. Strings
2. Work with strings
3. Performance of string concatenation
4. C-like representation of strings based on typed arrays

Variable initialization


Always declare variables in meaning and semantics, fixing them at the top of the scope. Initialization of variables on each line one by one is welcome. Of course, you can declare the var statement once, and then specify variables using a comma, but be consistent across the whole project.
 //  var foo = 1, bar = 2; var baz; var pony; var a , b; 


 //  var foo = 1; if (foo > 1) { var bar = 2; } 

Anyway, you can see exactly where the specific variable is declared.
 //  var foo = 1; var bar = 2; var baz; var pony; var a; var b; 


 //  var foo = 1; var bar; if (foo > 1) { bar = 2; } 


You can declare empty variables in one line separated by commas.

 //  var a = 'a'; var b = 2; var i, j; 


Conditional constructions


Use curly braces. In some cases, this will help you avoid a critical bug with Apple products while the SSL / TLS secure connection protocol is running.

 //  if (err) throw err; 


 //  if (err) { throw err; } 


For the sake of understanding the content, try to keep the contents of the condition block not on one line.
 //  if (err) { throw err; } 


To read:

1. Apple's SSL / TLS bug
2. Here it is fail

Comparisons


Avoid using == and! = Operators, use more favorable comparison operators === and! ==. These operators are called hard comparison operators, while their alternatives (== and! =) Transform operands to the same data type.

 //  function isEmptyString (text) { return text == ''; } isEmptyString(0); // <- true 


 //  function isEmptyString (text) { return text === ''; } isEmptyString(0); // <- false 


Ternary operator


The ternary operator is clearly suitable for specific conditions and is completely unsuitable for multi-component ones. As a rule, if your trained eye cannot make out a condition in the ternary operator as quickly as your brain can quickly read the text and interpret it, for the sake of your good, do not use the ternary operator.

jQuery is a prime example that is filled with unpleasant three-component operators .

 //  function calculate (a, b) { return a && b ? 11 : a ? 10 : b ? 1 : 0; } 


 //  function getName (mobile) { return mobile ? mobile.name : 'Generic Player'; } 


In cases where the condition may be confusing, just use if and else .

Functions


When initializing a function, use a functional declaration instead of functional expressions . All this affects the "lifting" of variables and the declaration of functions.

 //  var sum = function (x, y) { return x + y; }; 


 //  function sum (x, y) { return x + y; } 


There is nothing wrong with functional expressions if you use them in currying.

Keep in mind that the functional declaration of the functions will also be available in the scope above, so all of this does not matter in what order this function was declared. As a rule, you should always declare functions in the global scope, and you should try to avoid placing such functions within conditional statements.

 //  if (Math.random() > 0.5) { sum(1, 3); function sum (x, y) { return x + y; } } 


 //  if (Math.random() > 0.5) { sum(1, 3); } function sum (x, y) { return x + y; } 


 //  function sum (x, y) { return x + y; } if (Math.random() > 0.5) { sum(1, 3); } 


If you need an empty ( no-op ) method, you can either use an extension using the Function.prototype prototype or use the function noop () {} function . Also, ideally, you should have one reference to your own method, which is used throughout the application. Instead of writing the same type of code constructs, your method will be a template for similar constructs.

 //  var divs = document.querySelectorAll('div'); for (i = 0; i < divs.length; i++) { console.log(divs[i].innerHTML); } 


 //  var divs = document.querySelectorAll('div'); [].slice.call(divs).forEach(function (div) { console.log(div.innerHTML); }); 


Binding can be done using the function .call () from the prototype of the Function.prototype function, the record can also be reduced to [] .slice.call (arguments) instead of using Array.prototype.slice.call (). In any case, it can be simplified by using the bind () function.

However, it should be remembered that there is a significant performance degradation in the V8 engine when using this approach.

 //  var args = [].slice.call(arguments); 


 //  var i; var args = new Array(arguments.length); for (i = 0; i < args.length; i++) { args[i] = arguments[i]; } 


Do not declare functions inside loops.

 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { setTimeout(function () { console.log(values[i]); }, 1000 * i); } 


 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { setTimeout(function (i) { return function () { console.log(values[i]); }; }(i), 1000 * i); } 


 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { setTimeout(function (i) { console.log(values[i]); }, 1000 * i, i); } 


 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { wait(i); } function wait (i) { setTimeout(function () { console.log(values[i]); }, 1000 * i); } 


Or even better, just use .forEach , which is optimized for use cases in a loop.
 //  [1, 2, 3].forEach(function (value, i) { setTimeout(function () { console.log(value); }, 1000 * i); }); 


In order to view the call stack much easier, you need to reduce the use of anonymous functions. That is, if you are used to assigning all your callbacks as anonymous functions, you can try assigning them names. This will determine the root cause of the exception when analyzing the stack trace.

 //  function once (fn) { var ran = false; return function () { if (ran) { return }; ran = true; fn.apply(this, arguments); }; } 


 //  function once (fn) { var ran = false; return function run () { if (ran) { return }; ran = true; fn.apply(this, arguments); }; } 


Avoid nested conditions in functions; sometimes it is better to use an empty return value, thus your code will be more readable.

 //  function foo (car, black, turbine) { if (car) { if (black) { if (turbine) { return 'batman!'; } } } } 


 //  function fn (condition) { if (condition) { // 10+   } } 


 //  function foo (car, black, turbine) { if (!car) { return; } if (!black) { return; } if (!turbine) { return; } return 'batman!'; } 


If the function returns nothing or returns an empty return, then it returns the value undefined .

 //  function fn (condition) { if (!condition) { return; } // 10+   } 


To read:

1. Scope in JavaScript and "raising" variables and function declarations
2. Currying
3. Using the empty function, using jQuery as an example
4. Massive objects
5. stack trace
6. Tips for debugging javascript in asynchronous call stacks
7. JavaScript return in the function returns undefined

Prototypes and Inheritance


At all costs, avoid extending standard prototypes. If you need to extend the functionality of native data types (structures) of a language, use the poser library or develop your own implementation of the data structure.

Basic data structures:


Do not confuse primitive values ​​with object values ​​(true for String, Number, Boolean).

 //  String.prototype.half = function () { return this.substr(0, this.length / 2); }; 


 //  function half (text) { return text.substr(0, text.length / 2); } 


Avoid the prototype model of inheritance, because it can affect performance. One of the common mistakes in programming in JavaScript is just the extension of the basic prototypes. This technology, called monkey patching, violates the principle of encapsulation. Despite the fact that it is used in common frameworks such as Prototype.js, there are currently no reasonable reasons for its use, since in this case, the built-in types are cluttered with additional non-standard functionality. The only justification for extending the base prototypes is just emulating new features, such as Array.forEach, for old versions of the language that do not support them.



To read:

1. JavaScript data types and data structures
2. Determination of data type
3. What is a prototype?
4. Prototype-oriented programming
5. Inheritance and prototype chain
6. What is this and context definition in practice

Objects


To initialize an object, we can use curly braces {} , which will be an object literal. Use the factory creation approach instead of using a pure constructor to create an object.

Creating an object:
 var World = {}; //  ,       console.log(World); // Object {} 


 var World = { people: "~ 7 .", country: "~ 258 " }; console.log(World); // Object {people: "~ 7 .", country: "~ 258 "} 


Creating an object using a custom prototype (approach in using the constructor):
 //  // ,   -     var TemplateWorld = function(_people, _country) { //   ,     this       // TemplateWorld        this.people = _people; this.country = _country; } //  (    ) var World = new TemplateWorld("~ 7 .", "~ 258 "); console.log(World); // TemplateWorld {people: "~ 7 .", country: "~ 258 "} 


Creating an object using a custom prototype (approach to the use of factories):
 //  var TemplateWorld = function(_people, _country) { return { people: _people, country: _country }; } var World = TemplateWorld("~ 7 .", "~ 258 "); console.log(World); // Object {people: "~ 7 .", country: "~ 258 "} 


A good example of prototyping:
 //  function util (options) { //      var foo; function add () { return foo++; } function reset () { //  ,       foo = options.start || 0; } reset(); return { //      uuid: add }; } 


Copy by reference and pass by value

More clearly and transparently, how data is transferred between memory cells can be seen in C / C ++. But in JavaScript, it is very desirable to remember about the mechanism of operation of objects and then some questions will disappear immediately.

Variables
 //      //   ,      var a = 'text'; var b = a; //    a = 'update'; console.log(a); // update console.log(b); // text 


Objects
 //      //  JavaScript  c  var a = {foo: 'bar'}; var b = a; //    // b -   a a.foo = 'foo'; console.log(a); // Object {foo: 'foo'} console.log(b); // Object {foo: 'foo'} b.foo = 'bar'; console.log(a); // Object {foo: 'bar'} console.log(b); // Object {foo: 'bar'} 


To read:

1. Objects: transmission by reference

Arrays


We can use square brackets [] , which will be an array literal, to initialize the array. To increase performance, you can create an array using the new Array ( length ) construct with its length (array size).

In order to properly manipulate the elements of an array, you need to know the standard methods. Everything is much simpler than you can imagine.

Standard methods:


More advanced methods:


Copy by reference

 //  -     var a = [1, 2, 3]; var b = a; //    // b -   a a[2] = 4; console.log(a); // [1, 2, 4] console.log(b); // [1, 2, 4] b[2] = 3; console.log(a); // [1, 2, 3] console.log(b); // [1, 2, 3] 


Let's start studying standard methods:



image

Enumerating elements is done using .forEach

This is one of the simplest JavaScript methods. Not supported in IE7 and IE8.
Accepts a callback function (callback), which is called once for each element in the array, and is passed through three main arguments:


In addition, we can pass an optional second argument (object, array, variable, whatever), this argument will be available in the callback function and presented as a context (this).

 ['_', 't', 'a', 'n', 'i', 'f', ']'].forEach(function (value, index, array) { this.push(String.fromCharCode(value.charCodeAt() + index + 2)) }, out = []) out.join('') // <- 'awesome' 


We cheated, .join, we have not yet considered, but soon we get to this. In our case, it combines various elements in the array, this method works much more efficiently than doing it manually out [0] + '' + out [1] + '' + out [2] + '' + out [n] . By the way, we cannot break the foreach-cycle, as it is done in ordinary searches using break . Fortunately, we have other ways.

Checks with .some and .every

These methods are related to assert functions. If you have ever worked with enums in .NET, you’ll understand that they look like their cousins ​​.Any (x => x.IsAwesome) and .All (x => x.IsAwesome).

These methods are similar to .forEach in that they also accept a callback function with the same arguments, but are slightly different in nature.

The some () method calls the passed callback function once for each element present in the array until it finds one for which the callback returns the true value (the value that becomes true when casting to Boolean type). If such an element is found, the some () method will immediately return true. Otherwise, if callback returns false for all elements of the array, the some () method returns false. The callback function is called only for array indices that have assigned values; it is not called for indexes that have been deleted or to which values ​​have never been assigned.

 max = -Infinity satisfied = [10, 12, 10, 8, 5, 23].some(function (value, index, array) { if (value > max) max = value return value < 10 }) console.log(max) // <- 12 satisfied // <- true 


The .every () method works in the same way, but closures only happen when your callback function returns false, not the truth.

Merge with .join and .concat

The .join method is often confused with the .concat method, as you know, the method accepts a separator in the .join (separator) argument, it creates a string, as a result, it takes each element of the array and separates them with a separator in this string. If no separator is specified, the default is separator = ','. The concat () method returns a new array consisting of the array on which it was called, connected to other arrays and / or values ​​passed as arguments.



An incomplete copy means that the copy will contain the same object references as the original array.
As a rule, both the original and the new array refer to the same object.
That is, if the object by reference is changed, the changes will be visible both in the new and in the original arrays.

 var a = { foo: 'bar' } var b = [1, 2, 3, a] var c = b.concat() console.log(b === c) // <- false a.foo = 'foo'; console.log(b); // [1, 2, 3, Object {foo: 'foo'}] console.log(c); // [1, 2, 3, Object {foo: 'foo'}] b[3] === a && c[3] === a // <- true 


Working with the stack and queue with .pop, .push, .shift, and .unshift

Nowadays, everyone knows that adding elements to the end of an array is done using .push. Can you immediately add multiple elements using the [] .push ('a', 'b', 'c', 'd', 'z') construct?

 var a = [].push('a', 'b', 'c', 'd', 'z'); console.log(a); // 5 

 var a = []; a.push('a', 'b', 'c', 'd', 'z'); console.log(a); // ['a', 'b', 'c', 'd', 'z'] 


The pop () method removes the last element from the array and returns its value. If the array is empty, returns undefined (void 0).

Using .push and .pop we can develop our own LIFO stack structure.

 function Stack () { this._stack = [] } Stack.prototype.next = function () { return this._stack.pop() } Stack.prototype.add = function () { return this._stack.push.apply(this._stack, arguments) } stack = new Stack() stack.add(1, 2, 3) stack.next() // <- 3 stack.next() // <- 2 stack.next() // <- 1 stack.next() // <- undefined 


On the contrary, we can create a FIFO queue using .unshift and .shift.

 function Queue () { this._queue = [] } Queue.prototype.next = function () { return this._queue.shift() } Queue.prototype.add = function () { return this._queue.unshift.apply(this._queue, arguments) } queue = new Queue() queue.add(1,2,3) queue.next() // <- 1 queue.next() // <- 2 queue.next() // <- 3 queue.next() // <- undefined 


Using .shift (or .pop) in a loop for a set of array elements, we can clear it in the process.

 list = [1,2,3,4,5,6,7,8,9,10] while (item = list.shift()) { console.log(item) } list // <- [] 


Enumeration method (mapping) .map

map() .

map callback . callback , , undefined. ( , , ).

Array.prototype.map , .forEach, .some, .every:
.map(fn(value, index, array), thisArgument).

 values = [void 0, null, false, ''] values[7] = 'text' result = values.map(function(value, index, array){ console.log(value) return value }) // <- [undefined, null, false, '', undefined × 3, undefined] console.log(result[7]); // text 


undefined × 3 — , .map , - . .map .

 //  [1, '2', '30', '9'].map(function (value) { return parseInt(value, 10) }) // 1, 2, 30, 9 [97, 119, 101, 115, 111, 109, 101].map(String.fromCharCode).join('') // <- 'awesome' //       items.map(function (item) { return { id: item.id, name: computeName(item) } }) 


.filter

filter() , , .

filter() callback , , , callback true , true boolean. callback , ; , . , callback, .

: .filter(fn(value, index, array), thisArgument). , .filter , callback-, .

 [void 0, null, false, '', 1].filter(function (value) { return value }) // <- [1] [void 0, null, false, '', 1].filter(function (value) { return !value }) // <- [void 0, null, false, ''] 


.sort

sort() . . c Unicode.

: Array.prototype.sort(fn(a,b)), , , :



 [9,80,3,10,5,6].sort() // <- [10, 3, 5, 6, 80, 9] [9,80,3,10,5,6].sort(function (a, b) { return a - b }) // <- [3, 5, 6, 9, 10, 80] 


.reduce, .reduceRight

reduce() callback , , , : ( callback), , , .

, reduce() reduceRight() , , reduce() , reduceRight() .

: reduce(callback(previousValue, currentValue, index, array), initialValue).

previousValue currentValue . reduce() initialValue, previousValue initialValue, currentValue . initialValue , previousValue , currentValue .

.reduce :
 Array.prototype.sum = function () { return this.reduce(function (partial, value) { return partial + value }, 0) }; [3,4,5,6,10].sum() // <- 28 


, . .join . , :
 function concat (input) { return input.reduce(function (partial, value) { if (partial) { partial += ', ' } return partial + value.name }, '') } concat([ { name: 'George' }, { name: 'Sam' }, { name: 'Pear' } ]) // <- 'George, Sam, Pear' 


.slice

.concat, .slice - . — . Array.prototype.slice .

 Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 }) // <- ['a', 'b'] 


.concat:
 Array.prototype.concat.call({ 0: 'a', 1: 'b', length: 2 }) // <- [{ 0: 'a', 1: 'b', length: 2 }] 


, .slice — :
 function format (text, bold) { if (bold) { text = '<b>' + text + '</b>' } var values = Array.prototype.slice.call(arguments, 2) values.forEach(function (value) { text = text.replace('%s', value) }) return text } format('some%sthing%s %s', true, 'some', 'other', 'things') // <- <b>somesomethingother things</b> 


.splice

splice() , / . , . , , .concat .slice.

 var source = [1,2,3,8,8,8,8,8,9,10,11,12,13] var spliced = source.splice(3, 4, 4, 5, 6, 7) console.log(source) // <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13] spliced // <- [8, 8, 8, 8] 


It may have already been noted that it also returns deleted items and sometimes it can be useful.
 var source = [1,2,3,8,8,8,8,8,9,10,11,12,13] var spliced = source.splice(9) spliced.forEach(function (value) { console.log('removed', value) }) // <- removed 10 // <- removed 11 // <- removed 12 // <- removed 13 console.log(source) // <- [1, 2, 3, 8, 8, 8, 8, 8, 9] 


Search for an element in an .indexOf array

The indexOf () method compares the searchElement element with the elements in the array using a strict comparison (the same method is used by the === operator, the triple is equal).

 var a = { foo: 'bar' } var b = [a, 2] console.log(b.indexOf(1)) // <- -1 console.log(b.indexOf({ foo: 'bar' })) // <- -1 console.log(b.indexOf(a)) // <- 0 console.log(b.indexOf(a, 1)) // <- -1 b.indexOf(2, 1) // <- 1 b.indexOf(2, a) // <- 1 b.indexOf(a, 2) // <- -1 


To help operator in

A common mistake of newbies at the interview is their confused opinion about the identical operation of the .indexOf method and the in operator.
 var a = [1, 2, 5] 1 in a // <- true //     a[1],   2! 5 in a // <- false //   a[5]   


The fact is that the in operator checks the key of the object, and does not search by value. This option works much faster than using .indexOf:

 var a = [3, 7, 6] 1 in a === !!a[1] // <- true 


Reverse a search or reversal of an array using .reverse

This method will take the elements in the array and place them in reverse order.

 var a = [1, 1, 7, 8] a.reverse() // [8, 7, 1, 1] 


To read:

1. Array
2. Array vs. Object
3. JavaScript
4.
5. Objects/Arrays JavaScript
6.
7. , ,


/ / , . . , (inline), .

 //  if (/\d+/.test(text)) { // non-precompiled, but faster console.log('so many numbers!'); } 


 //  var numeric = /\d+/; // precompiled if (numeric.test(text)) { console.log('so many numbers!'); } 


, , . , .

:

1.
2. RegExp
3. C
4. RegExp String
5. JavaScript precompiled
6.
7.


- console, . . , . , . - (console.log

:

1. JavaScript
2. console
3. .
4. Chrome. Web Inspector
5. Chrome console API

Comments


, . . , , , , . , . , .

 //  //    var p = $('<p/>'); p.center(div); p.text('foo'); 

 //  var container = $('<p/>'); var contents = 'foo'; container.center(parent); container.text(contents); megaphone.on('data', function (value) { container.text(value); // megaphone      }); var numeric = /\d+/; if (numeric.test(text)) { console.log('so many numbers!'); } 


, !

:

1. 16
2.
3.
4. JavaScript-


. , , .

 //  function a (x, y, z) { return (x+y+z) / 3; } a(1, 3, 5); // <- 3 


 //  function average(a, b, c) { return (a + b + c) / 3; } average(1, 3, 5); // <- 3 


:

1. JavaScript Style Guide and Coding Conventions

Polyfill-


, , , polyfill-, . , , .

polyfill-, , , polyfill.

:

1. DOM:
2. 10 polyfill-
3. polyfill-


1. || , . , (false || true). , - , false, 0, null '', , , . : if (value === void 0) { value = defaultValue }

 function a (value) { var defaultValue = 33; var used = value || defaultValue; } 


2. , .bind
 function sum (a, b) { return a + b; } var addSeven = sum.bind(null, 7); addSeven(6); // <- 13 


3. Array.prototype.slice.call ,
 var args = Array.prototype.slice.call(arguments); 


4. !
 var emitter = contra.emitter(); // example, event emitters: jQuery, Angular, React .. body.addEventListener('click', function () { emitter.emit('click', e.target); }); emitter.on('click', function (elem) { console.log(elem); }); //   emitter.emit('click', document.body); 


5. (no-op), Function()
 function (cb) { setTimeout(cb || Function(), 2000); } 


:

1. browserhacks
2. 5 JavaScript-
3. JavaScript
4.
5. JavaScript: arguments

ES6


JavaScript ECMA ( W3C), ECMAScript. ECMAScript :



2009 ES5 ( ES5.1 2011), , Firefox, Chrome, Opera, Safari . JS ( 2013, 2014, 2015) — ES6.

ES6 — . , JS (ES5), ES6 , . ! ES6 . . . JS, -. - , ( ).

:

1. Style Guide ES6
2. ES6
3. ES6
4. ES6 :
5. ES6
6. ECMAScript 6
7. 350 ES6

Source: https://habr.com/ru/post/281110/


All Articles