• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# JavaScript Coding Style Guide
2
3## Goal
4Rules are not perfect. Prohibiting features that are useful in specific situations can have an impact on code implementation, but we set the rules for the benefit of most programmers. If we identify a rule cannot be followed in the operations, we should work together to improve the rule. You are supposed to have the basic JavaScript language capabilities to refer to this guide, instead of learning the JavaScript language from it.
5
6## General Principles
7The code is required to be **readable, maintainable, secure, reliable, testable, efficient, and portable** on the premise that the functions are correct.
8
9## Convention
10
11**Rule**: Conventions that must be complied with during programming
12**Recommendation**: Conventions that must be considered during programming
13
14It is important to understand why this convention is so stated in both "Rules" or "Recommendations" and make efforts to comply.
15
16## Exceptions
17
18If the General Principle is not violated, the rules can be properly violated after full consideration and sufficient reasons are provided.
19Exceptions compromise code consistency so please avoid exceptions. Exceptions to "Rules" should be rare.
20
21The style consistency principle is preferred in the following situations:
22**When modifying external open-source code and third-party code, comply with the existing rules of the open-source code and third-party code and keep the style consistent. **
23
24## Programming Regulations
25
26### Naming Regulations
27
28#### Rule 1.1 Use correct English spellings to name, no use of pinyin spellings.
29
30**Counterexample:**`xingming`,`zhanghao`
31
32**Example:**`username`,`account`
33
34#### Rule 1.2 Use abbreviations as few as possible, except for common words or professional words. For example, `context` can be shortened to `ctx`, `request` can be shortened to `req`, and `response` can be shortened to `resp`.
35
36**Note:** Complete spelling of words can avoid unnecessary misunderstanding.
37
38**Exceptions:** The variable name of the cyclic condition can be ` i` or ` j` in the cyclic language.
39
40#### Rule 1.3 Class name, enumeration name and namespace name should comply the `upperCamelCase` style.
41
42**Example:**
43
44```javascript
45// Class name
46class User {
47  constructor(username) {
48    this.username = username;
49  }
50
51  sayHi() {
52    console.log(`hi, ${this.username}`);
53  }
54}
55
56// Enumeration name
57const UserType = {
58  TEACHER: 0,
59  STUDENT: 1
60};
61
62// Namespace
63const Base64Utils = {
64  encrypt: function(text) {
65    // todo encrypt
66  },
67  decrypt: function(text) {
68    // todo decrypt
69  }
70};
71```
72
73#### Rule 1.4 Variable name, method name, and parameter name should comply the `lowerCamelCase` style.
74
75**Example:**
76
77```javascript
78let msg = 'Hello world';
79
80function sendMsg(msg) {
81  // todo send message
82}
83
84function findUser(userID) {
85  // todo find user by user ID
86}
87```
88
89#### Rule 1.5 The names of static constants and enumeration values must be in upper case, and words are separated by underscores (_).
90
91**Example:**
92
93```javascript
94const MAX_USER_SIZE = 10000;
95
96const UserType = {
97  TEACHER: 0,
98  STUDENT: 1
99};
100```
101
102#### Recommendation 1.6 Do not use negative Boolean variable names. Local variables or methods of the Boolean type must be prefixed with expressions with the meaning of right or wrong.
103
104**Counterexample:**
105
106```javascript
107let isNoError = true;
108let isNotFound = false;
109function empty() {}
110function next() {}
111```
112
113**Example:**
114
115```javascript
116let isError = false;
117let isFound = true;
118function isEmpty() {}
119function hasNext() {}
120```
121
122### Code Format
123
124#### Rule 2.1 Use two spaces to indent, and do not use the `tab` character.
125
126**Note:** Only spaces are allowed for indentation. Two spaces are allowed at a time. Tab characters are not allowed for indentation.
127
128**Example:**
129
130```javascript
131const dataSource = [
132  {
133    id: 1,
134    title: 'Title 1',
135    content: 'Content 1'
136  },
137  {
138    id: 2,
139    title: 'Title 2',
140    content: 'Content 2'
141  }
142];
143
144function render(container, dataSource) {
145  if (!container || !dataSource || !dataSource.length) {
146    return void 0;
147  }
148
149  const fragment = document.createDocumentFragment();
150  for (let data of dataSource) {
151    if (!data || !data.id || !data.title || !data.content) {
152      continue;
153    }
154    const element = document.createElement("div");
155    const textNode = document.createTextNode(`${data.title}: ${data.content}`);
156    element.appendChild(textNode);
157    element.setAttribute("id", data.id);
158    fragment.appendChild(element);
159  }
160  container.appendChild(fragment);
161}
162
163```
164
165#### Rule 2.2 The line width cannot exceed 120 characters.
166
167**Note:** It is recommended that each line should contain no more than 120 characters. Use a proper method to break the line if the line contain more than 120 characters.
168
169**Exception:** If a line of comments contains more than 120 characters of commands or URLs, keep it in one line for easy copying, pasting, and searching by running the grep command. The preprocessed error information is easy to read and understand in one line, even if it contains more than 120 characters.
170
171#### Rule 2.3 The use of braces must comply with the following conventions:
172
1731. If the value in the braces is empty, the value can be abbreviated as `{}` without a newline.
1742. The left braces do not contain a line feed, and the left braces are followed by a line feed.
1753. Line feeds before the right brace. If there is `else` or `catch` after the brace, line feeds are not required. In other cases, line feeds are required.
176
177#### Rule 2.4 Implementations of conditional and loop statements must be enclosed in braces, even if there is only one statement.
178
179**Counterexample:**
180
181```javascript
182if (condition)
183  console.log('success');
184
185for(let idx = 0; idx < 5; ++idx)
186  console.log(idx);
187```
188
189**Example:**
190
191```javascript
192if (condition) {
193  console.log('success');
194}
195
196for(let idx = 0; idx < 5; ++idx) {
197  console.log(idx);
198}
199```
200
201#### Rule 2.5 Condition statements and loop statements cannot be written in one line.
202
203**Counterexample:**
204
205```javascript
206if (condition) { /* todo something */ } else { /* todo other */ }
207
208let idx = 0;
209while(idx < 10) console.log(idx);
210```
211
212**Example:**
213
214```javascript
215if (condition) {
216  /* todo something */
217} else {
218  /* todo other */
219}
220
221let idx = 0;
222while(idx < 10) {
223  console.log(idx);
224}
225```
226
227#### Rule 2.6 The `case` and `default` in the `switch` statement must be indented by one layer.
228
229**Example:**
230
231```javascript
232switch(condition) {
233  case 0:
234    doSomething();
235    break;
236  case 1: { // the braces is not necessary
237    doOtherthing();
238    break;
239  }
240  default:
241    break;
242}
243```
244
245#### Rule 2.7 The line feeds of expressions must be consistent, and the operator must be placed at the end of the line.
246
247**Note:** If a long expression does not meet the line width requirement, you need to wrap the line in a proper position. Generally, in the late phrase of the lower-priority operator or connector, the operator or connector should be placed at the end of the line. The operator and separator are placed at the end of the line, indicating that there is not the end.
248
249**Example:**
250
251```javascript
252// if the condition statement exceeds the line width.
253if (userCount > MAX_USER_COUNT ||
254  userCount < MIN_USER_COUNT) {
255  doSomething();
256}
257
258const sum =
259  number1 +
260  number2 +
261  number3 +
262  number4 +
263  number5 +
264  number6 +
265  number7 +
266  number8 +
267  number9;
268```
269
270#### Rule 2.8 Multiple variable definitions and assignment statements cannot be written in one line.
271
272**Counterexample:**
273
274```javascript
275let maxCount = 10, isCompleted = false;
276
277let pointX, pointY;
278pointX = 10; pointY = 0;
279```
280
281**Example:**
282
283```javascript
284let maxCount = 10;
285let isCompleted = false;
286
287let pointX = 0;
288let pointY = 0;
289```
290
291#### Rule 2.9 Spaces should highlight keywords and important information. Avoid unnecessary spaces.
292
293**Note:** Spaces reduce code density and increase code readability. The general rules are as follows:
294
2951. Add a spaces after keywords `if`、`elseif`、`else`、`switch`、`while`、`for`.
2962. No space is added between the parentheses.
2973. Spaces must be added on both sides of the braces, except for simple scenarios such as `{}`.
2984. No space is added between multiple parentheses.
2995. No space is added after unary operators (`&`, `*`, `+`, `-`, `!`,etc.).
3006. Add a space on the left and right side of binary operators `=`、`+`、`-`、`*`、`/`、`%`、`|`、`&`、`||`、`&&`、`<`、`>`、`<=`、`>=`、`==`、`!=`、`===`、`!==`, etc.)
3017. Add a space on the left and right side of ternary operator (`?: `).
3028. No space is added between the preceded or post-decrease (`++`, `--`) and variables.
3039. Add a space before a comma (`, `).
30410. Add a space after `//` in a single line.
30511. No space is added at the end of the line.
306
307#### Rule 2.10 Expression statements must end with a semicolon.
308
309**Counterexample:**
310
311```javascript
312let username = 'jack'
313let birthday = '1997-09-01'
314
315console.log(`${username}'s birthday is ${birthday}`)
316```
317
318**Example:**
319
320```javascript
321let username = 'jack';
322let birthday = '1997-09-01';
323
324console.log(`${username}'s birthday is ${birthday}`);
325```
326
327#### Recommendation 2.11 Use single quotation marks to wrap strings first.
328
329**Example:**
330
331```javascript
332let message = 'wolrd';
333console.log(message);
334```
335
336### Code instructions
337
338#### Rule 3.1 When declaring a variable, use the keyword `var`, `let`, or `const` to prevent the variable from being exposed to the global scope.
339
340**Note:** If the keyword `var`, `let`, or `const` is not used to declare a variable, the variable will be exposed to the global scope, which may overwrite the variable with the same name in the global scope. As a result, the GC cannot effectively reclaim the memory. In addition, when a variable contains sensitive information, exposuring to the global scope may result in information leakage. ** Use `const` instead of `var` for all references; Use `let` instead of `var` if you need a variable reference.** Because the scope of `const` and `let` is smaller, writing code is easier to control. Const ensures that the reference cannot be re-assigned. The pointer referenced by const is immutable, and an error will be reported during re-assignment, avoiding overwriting.
341
342**Counterexample:**
343
344```javascript
345function open() {
346  url = 'http://127.0.0.1:8080'; //url will be exposed to the global scope
347  //todo something
348}
349open();
350console.log(url); //url can be accessed, output: http://127.0.0.1:8080
351```
352
353**Example:**
354
355```javascript
356// ES5.1 Using var to declare variables
357function open() {
358  var url = 'http://127.0.0.1:8080';
359  // todo something
360}
361open();
362console.log(url); //Report: Uncaught ReferenceError: url is not defined
363```
364
365```javascript
366// In ES6, the let and const keywords are preferred to declare variables.
367function open() {
368  const url = 'http://127.0.0.1:8080';
369  //todo something
370}
371open();
372console.log(url); //Report: Uncaught ReferenceError: url is not defined
373```
374
375#### Rule 3.2 Function expressions must be used to declare functions in function blocks.
376
377**Note:** Although many JS engines support in-block declaration functions, they do not belong to the ECMAScript specification. The poor implementation of browsers is incompatible with each other, and some are contrary to the future ECMAScript draft. In addition, ECMAScript5 does not support block scopes. All control flows are not independent scopes. Variables or functions declared in the control flows are in the scope of their parent functions or scripts. As a result, the declaration of functions or variables in blocks may be overwritten. If you do need to define a function in a block, you should initialize it using a function expression.
378
379**Counterexample:**
380
381```javascript
382function bar(name) {
383  if (name === "hotel") {
384    // 1. Define a foo function. The function scope is not the 'if' code block but the 'bar' function scope.
385    function foo() {
386      console.log("hotel foo A");
387    }
388  } else {
389    // 2. Define the 'foo' function again to overwrite the 'foo' function definition under the 'if' condition branch.
390    function foo() {
391      console.log("hotel foo 2");
392    }
393  }
394  foo && foo();
395}
396bar("hotel"); // output is shown as"hotel foo 2"
397```
398
399**Example:**
400
401```javascript
402function bar(name) {
403  var foo;
404  if (name == "hotel") {
405    foo = function () {
406      console.log("hotel foo 1");
407    };
408  } else {
409    foo = function () {
410      console.log("hotel foo 2");
411    }
412  }
413  foo && foo();
414}
415bar("hotel"); // Correct output"hotel foo 1"
416```
417
418#### Rule 3.3 Encapsulation of Basic Types is prohibited
419
420**Note:** JavaScript has five basic data types: Undefined, Null, Boolean, Number, and String. The value of the base data type is unchangeable. The basic data type object used in JavaScript is only a value. It does not contain the methods and attributes of the object encapsulated by the object. When the attributes and methods are not required, the encapsulation type of the object does not need to be used.
421
422**Counterexample:**
423
424```javascript
425var isShow = new Boolean(false);
426if (isShow) {
427  alert('hi'); //It is executed, and the following information is displayed: hi
428}
429```
430
431**Example:**
432
433```javascript
434var isShow = false;
435if (isShow) {
436  alert('hi');
437}
438```
439
440#### Rule 3.4 The use of `with` is prohibited
441
442**Note:** Using 'with' makes your code semantically unclear, because objects of 'with' may conflict with local variables, changing the original meaning of the program.
443
444**Counterexample:**
445
446```javascript
447var foo = { x: 5 };
448with(foo) {
449  var x = 3;
450  console.log(x); //Output: 5
451}
452```
453
454#### Rule 3.5 `this` can only be used in object constructors, methods, and closures.
455
456**Note:** In JavaScript, the "this" pointer represents the owner of the object that executes the current code. This has special semantics:
457
458+ Global objects (in most cases)
459+ Scope of the caller (when eval is used)
460+ Nodes in the DOM tree (when adding event handling functions)
461+ Newly created object (using a constructor)
462+ Other objects (if the function is called() or apply())
463
464```javascript
465var User = function(username) {
466  this.username = username;
467};
468var user = new User('John');
469console.log(user.username); // Output: John
470
471var ClickCounter = {
472  value: 0,
473  click: function() {
474    ++this.value;
475  },
476  getValue() {
477    return this.value;
478  }
479};
480console.log(Counter.getValue()); //Output: 0
481Counter.click();
482console.log(Counter.getValue()); //Output: 1
483```
484
485#### Rule 3.6 Do not use conditional comments in IE.
486
487**Note:** Conditional compilation can be activated using the `\@cc_on` statement or the `\@if` or `\@set` statement in IE. Although comments can be made to be compatible with browsers other than IE, they hinder the execution of automation tools because they change the JavaScript syntax tree at run time.
488
489**Counterexample:**
490
491```javascript
492var f = function () {
493  /*@cc_on @*/
494  /*@if (@_jscript_version >= 4)
495       alert("JavaScript version 4 or better");
496    @else @*/
497  alert("Conditional compilation not supported by this scripting engine.");
498  /*@end @*/
499};
500```
501
502#### Rule 3.7 Prototypes of built-in objects cannot be modified.
503
504**Note:** As a set of public interfaces, built-in objects have conventional behaviors. Modifying the prototype may damage the interface semantics or cause abnormalities during debugging.
505
506**Counterexample:**
507
508```javascript
509Array.prototype.indexOf = function () { return -1 }
510var arr = [1, 1, 1, 1, 1, 2, 1, 1, 1];
511console.log(aar.indexOf(2)); // Output:-1
512```
513
514#### Rule 3.8 Do not directly use the built-in attribute of `Object.prototype`.
515
516**Note:** ECMAScript 5.1 adds `Object.create`, which creates a new object and uses an existing object to provide the proto of the newly created object. `Object.create(null)` is a common pattern for creating objects used as maps. Unexpected behavior or vulnerability may occur when the object has an attribute with the same name as `Object.prototype`. For example, it is not safe for a web server to parse JSON input from a client and use `hasOwnProperty` to directly invoke the generated object, because a malicious client may send a similar JSON value `' {"hasOwnProperty": 1} '` and cause the server to crash.
517
518**Counterexample:**
519
520```javascript
521var hasBarProperty = foo.hasOwnProperty("bar");
522var isPrototypeOfBar = foo.isPrototypeOf(bar);
523var barIsEnumerable = foo.propertyIsEnumerable("bar");
524```
525
526**Example:**
527
528```javascript
529var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");
530var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);
531var barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar");
532```
533
534#### Rule 3.9 Use the `Object.getPrototypeOf` function instead of `_proto_`
535
536**Note:** ES5 introduces the `Object.getPrototypeOf` function as the standard API for obtaining object prototypes, but a large number of JavaScript engines have long used a special `proto' attribute to achieve the same purpose. However, `proto` is essentially an internal attribute rather than a formal external API. Currently, this attribute must be deployed in browsers, but not in other running environments. Therefore, this attribute is not fully compatible. For example, objects with null prototypes are handled differently in different environments.
537
538```javascript
539var empty = Object.create(null);
540"_proto_" in empty; //Some environments false is returned, some environments true is returned.
541```
542
543Therefore, use `Object.getPrototypeOf()` instead of using the proto attribute in terms of semantics and compatibility. The `Object.getPrototypeOf' function is valid in any environment and is a more standard and portable method for extracting object prototypes.
544
545#### Rule 3.10 Do not create functions with function constructors.
546
547**Note:** There are three methods for defining a function: function declaration, function constructor, and function expression. Regardless of in which method you define a function, they are instances of the Function object and inherit all default or custom methods and properties of the Function object. The method of creating a function using a function constructor is similar to the character string `eval()`. Any character string can be used as the function body, which may cause security vulnerabilities.
548
549**Counterexample:**
550
551```javascript
552var func = new Function('a', 'b', 'return a + b');
553var func2 = new Function('alert("Hello")');
554```
555
556**Example:**
557
558```javascript
559function func(a, b) {
560  return a + b;
561}
562
563var func2 = function(a, b) {
564  return a + b;
565}
566```
567
568#### Suggestion 3.11 When using the prototype `prototype' to implement inheritance, try to use the existing stable library methods instead of self-implementing them.
569
570**Note:** The multi-level prototype structure refers to the inheritance relationship in JavaScript. When you define a class D and use class B as its prototype, you get a multilevel prototype structure. These prototype structures can get complicated. Using existing stable library methods such as `goog.inherits()` of the Closure library or other similar functions can avoid unnecessary coding errors.
571
572#### Suggestion 3.12 When defining a class, you should define the method under the prototype and the attributes within the constructor.
573
574**Note:** There are multiple methods in JavaScript to add methods or members to constructors. However, using a prototype to define methods can reduce memory usage and improve running efficiency.
575
576**Counterexample:**
577
578```javascript
579function Animals() {
580  this.walk = function() {}; // This causes a walk method to be created on each instance.
581}
582```
583
584**Example:**
585
586```javascript
587function Animals() {}
588
589Animals.prototype.walk = function() {};
590```
591
592#### Suggestion 3.13 When using closures, avoid cyclic reference, which may cause memory leakage.
593
594**Note:**
595JavaScript is a garbage collection language in which the memory of an object is allocated to the object based on its creation and is reclaimed by the browser when there is no reference to the object. JavaScript's garbage collection mechanism is fine on its own, but browsers are somewhat different in the way they allocate and recover memory for DOM objects. Both IE and Firefox use reference counting to process memory for DOM objects. In the reference counting system, each referenced object keeps a count to see how many objects are referencing it. If the count is zero, the object is destroyed and the memory it occupies is returned to the heap. While this solution is generally effective, there are some blind spots in circular references. When two objects refer to each other, they form a circular reference, where the reference counting values of the objects are assigned to 1. In pure garbage collection systems, circular references are not a problem: if one of the two objects involved is referenced by any other object, both objects will be garbage collected. In a reference counting system, neither of these objects can be destroyed because reference counting can never be 0. In a hybrid system that uses both garbage collection and reference counting, a leak occurs because the system does not correctly recognize circular references. In this case, neither the DOM object nor the JavaScript object can be destroyed. Circular references are easy to create. Circular references are particularly prominent in closures, one of JavaScript's most convenient programming structures. Closures hold references to their external scopes (including local variables, parameters, and methods). When the closure itself is held by scope members (usually DOM objects), circular references are formed, which further leads to memory leaks.
596
597**Counterexample:**
598
599```javascript
600function setClickListener(element, a, b) {
601  element.onclick = function() {
602    // Use a and b here
603  };
604};
605```
606
607In the above code, the closure retains references to elements, a, and b even if element is not used. Because the element also retains the reference to the closure, a circular reference is generated and cannot be recycled by the GC.
608
609**Example:**
610
611```javascript
612function setClickListener(element, a, b) {
613  element.onclick = createHandler(a, b);
614}
615
616function createHandler(a, b) {
617  // By adding another function to avoid the closure itself, you can organize memory leaks.
618  return function() {
619    // Use a and b here
620  }
621}
622```
623
624#### Suggestion 3.14 Watch out for JavaScript floating point numbers.
625
626**Note:** JavaScript has a single numeric type: `IEEE 754` double-precision floating point number. Having a single numeric type is one of the best features of JavaScript. Multiple number types can be a source of complexity, confusion and error. However, one of the biggest drawbacks of the binary floating-point type is that it does not accurately represent the fractional part, causing unexpected precision problems, as shown in the following examples.
627
628Sample Code1:
629
630```javascript
631console.log(0.1 + 0.2 === 0.3); // Output: false. Therefore, do not use == or === to compare floating-point numbers.
632```
633
634Sample Code2:
635
636```javascript
637var sum1 = (0.1 + 0.2) + 0.3;
638console.log(sum1); // Output: 0.6000000000000001
639
640var sum2 = 0.1 + (0.2 + 0.3);
641console.log(sum2); // Output: 0.6. Therefore, for binary floating-point numbers, (a + b) + c cannot be guaranteed to produce the same result as a + (b + c).
642```
643
644The effective solutions are as follows:
645
6461. Use integers as much as possible because integers do not need to be rounded.
647
6482. The native JavaScript method `Number.prototype.toFixed(digits)`,`digist` is used to indicate the number of digits after the decimal point. The exponential method is not used. If necessary, the number is rounded off. This method is used to reduce the precision of the calculation result before determining the floating-point number calculation result. The sample code is as follows:
649
650   ```javascript
651   parseFloat(0.1 + 0.2).toFixed(1); //0.3
652   ```
653
6543. A very small constant `Number.EPSILON =.220446049250313e-16 ` is added to ES6, which is about 0.00000000000000022204. `Number.EPSILON` is used to determine the calculation error of floating-point numbers. If the calculation error of floating-point numbers is less than or equal to the value of `Number.EPSILON`, such an error is acceptable. The sample code is as follows:
655
656   ```javascript
657   function isNumberEquals(one, other) {
658     return Math.abs(one - other) < Number.EPSILON;
659   }
660   var one = 0.1 + 0.2;
661   var other = 0.3;
662   console.log(isNumberEquals(one, other)); // Output: true
663   ```
664
6654.  Use some class library methods that support precise calculation, such as `math.js`.
666
667   ```html
668   <!DOCTYPE html>
669   <html>
670     <head>
671       <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.js"></script>
672       <script type="text/javascript">
673         function fn_click() {
674           math.config({
675             number: "BigNumber",
676           });
677           var result = math.add(math.bignumber(0.1), math.bignumber(0.2));
678           alert(result);
679         }
680       </script>
681     </head>
682     <body>
683       <input type="button" value="mathjs(0.1+0.2)" onclick="fn_click();" />
684     </body>
685   </html>
686
687   ```
688
689#### Suggestion 3.15 Do not use the array constructor with variable arguments.
690
691**Note:** The method of constructor `new Array` is not recommended to construct a new array. If the constructor has only one parameter, exceptions may occur. In addition, the global definition of the array may be modified. Therefore, it is recommended to use the array literal notation, that is, `[]` notation, to create an array.
692
693**Counterexample:**
694
695```javascript
696const arr1 = new Array(x1, x2, x3);
697const arr2 = new Array(x1, x2);
698const arr3 = new Array(x1);
699const arr4 = new Array();
700```
701
702Except for the third case, all other functions can work properly. If `x1` is an integer, `arr3` is an array whose length is `x1` and values are `undefined`. If `x1` is any other number, an exception is thrown, and if it is anything else, it is an array of cells.
703
704**Example:**
705
706```javascript
707const arr1 = [x1, x2, x3];
708const arr2 = [x1, x2];
709const arr3 = [x1];
710const arr4 = [];
711```
712
713This way, you'll save a lot of trouble.
714
715Similarly, use `{}` instead of `new Object()` to create objects.
716
717#### Rule 3.16 String templates are preferred over string links when constructing strings.
718
719**Note:** The template character strings are more concise and readable.
720
721**Counterexample:**
722
723```javascript
724function sayHi(name) {
725  console.log('hi, ' + name);
726}
727```
728
729**Example:**
730
731```javascript
732function sayHi(name) {
733  console.log(`hi, ${name}`);
734}
735```
736
737#### Rule 3.17 Use `for...of` for array traversal and `for...in` for object traversal.
738
739**Counterexample:**
740
741```javascript
742let numbers = [1, 2, 3, 4];
743let sum = 0;
744for (let number in numbers) {
745  sum += number;
746}
747// sum === 00123;
748```
749
750**Example:**
751
752```javascript
753let numbers = [1, 2, 3, 4];
754let sum = 0;
755for (let number of numbers) {
756  sum += number;
757}
758// sum === 10
759```
760
761