Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the basic points of writing high-quality JavaScript code

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

What are the basic points of writing high-quality JavaScript code? I believe many inexperienced people don't know what to do about it. Therefore, this article summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

This summary also includes some habits that are less relevant to the code, but are relevant to the creation of the overall code, including writing API documentation, performing peer reviews, and running JSLint. These habits and practices can help you write code that is better, easier to understand and maintain, and you'll be proud to look back in a few months or years.

Write maintainable code (Writing Maintainable Code)

Software bug fixes are expensive, and the cost of these bug increases over time, especially when these bug lurk and slowly appear in released software. Fix bug as soon as you find it, and the problem your code is trying to solve is still clear in your mind. Otherwise, you will need to move to another task, forget that particular code, and look at the code after a while:

◆ takes the time to learn and understand the problem.

◆ time is to understand the problem code that should be solved.

There are also problems, especially for large projects or companies, the guy who fixed bug is not the one who wrote the code (and found that bug and bug are not the same person). Therefore, it is necessary to reduce the time it takes to understand the code, whether it is the code you wrote some time ago or that written by other members of the team. This is about the bottom line (revenue) and the well-being of developers, because we should develop new exciting things rather than spend hours and days maintaining legacy code.

Another fact about the life of software development is that it takes much more time to read code than to write it. Sometimes, when you focus on and think deeply about a problem, you can sit down and write a lot of code in an afternoon.

Your code will work very quickly, but as the application matures, there will be many other things that will require you to review, modify, and adjust. For example:

◆ bug is exposed.

New ◆ features are added to the application

◆ programs work in a new environment (for example, new idea browsers on the market)

◆ code repurposed

◆ code has to be completely rebuilt from scratch, or ported to another architecture, or even in another language

As a result of these changes, code that rarely takes hours to write ends up taking weeks to read. This is why creating maintainable code is critical to the success of your application.

Maintainable code means:

◆ readable

◆ consistent

◆ predictable

◆ looks like it was written by the same person.

◆ has been recorded

Minimum global variable (Minimizing Globals)

JavaScript manages scopes through functions. Variables declared inside the function are only inside the function, and are not available outside the function. Global variables, on the other hand, are declared outside any function or simply used without declaration.

Each JavaScript environment has a global object that you can access when you use this outside of any function. Every variable you create becomes an attribute of this global object. In the browser, for convenience, the global object has an additional property called window, and this window (usually) points to the global object itself. The following code snippet shows how to create and access global variables in a browser environment:

Myglobal = "hello"; / / console.log (myglobal) is not recommended; / / "hello" console.log (window.myglobal); / / "hello" console.log (window ["myglobal"]); / / "hello" console.log (this.myglobal); / / "hello"

The problem of global variables

The problem with global variables is that these global variables are shared by all the code on your JavaScript application and web pages, and they live in the same global namespace, so naming conflicts are inevitable when two different parts of the program define global variables with the same name but with different functions.

It is also common for a web page to contain code that is not written by the developers of the page, such as:

◆ third-party JavaScript library

Script code of ◆ advertiser

◆ third-party users track and analyze script code

◆ different types of widgets, logos and buttons

For example, the third-party script defines a global variable called result; and then defines a global variable named result in your function. The result is that the latter variable overrides the previous one, and the third-party script suddenly dies!

Therefore, it is important to use as few global variables as possible if you want to be a good neighbor with other scripts. Some of the strategies mentioned later in the book to reduce global variables, such as namespace schemas or functions that automatically execute immediately, but the most important thing to reduce the number of global variables is to always use var to declare variables.

Because of the two characteristics of JavaScript, it is surprisingly easy to create global variables unconsciously. First, you can use variables without even declaring them; second, JavaScript has an implicit global concept, which means that any variable you don't declare will become a global object property. Refer to the following code:

Function sum (x, y) {/ / not recommended: implicit global variable result = x + y; return result;}

The result in this code is not declared. The code still works fine, but your result is an extra global namespace after calling the function, which can be the source of a problem.

The rule of thumb is to always declare variables using var, as the improved version of the sum () function demonstrates:

Function sum (x, y) {var result = x + y; return result;}

Another counterexample of creating implicit global variables is to use a task chain to make a partial var declaration. In the following snippet, an is a local variable but b is a global variable, which may not be what you want to happen:

/ / counterexample, do not use function foo () {var a = b = 0; / /...}

The reason for this is that this right-to-left assignment, first of all, is the assignment expression b = 0, in which case b is undeclared. The return value of this expression is 0, which is then assigned to the local variable a defined by var. In other words, it's like you type:

Var a = (b = 0)

If you are ready to declare variables, it is better to use chain allocation and will not produce any unexpected global variables, such as:

Function foo () {var a, b; / /... A = b = 0; / / two uniform local variables}

However, another reason to avoid global variables is portability. If you want your code to run in a different environment (host), use global variables such as treading on thin ice, because you will inadvertently overwrite host objects that did not exist in your original environment (so you thought the name could be used boldly, in fact, it doesn't apply in some cases).

Forget the side effects of var (Side Effects When Forgetting var)

The small difference between implicit global variables and clearly defined global variables is the ability to make variables undefined through the delete operator.

Global variables created by ◆ through var (created in programs other than functions) cannot be deleted.

Implicit global variables created by ◆ without var (regardless of whether they are created in a function) can be deleted.

This shows that, technically, implicit global variables are not really global variables, but they are properties of global objects. Properties can be deleted through the delete operator, while variables cannot:

/ / define three global variables var global_var = 1; global_novar = 2; / / negative example (function () {global_fromfunc = 3; / / negative example} ()); / / attempt to delete delete global_var; / / false delete global_novar; / / true delete global_fromfunc; / / true / / Test the delete typeof global_var; / / "number" typeof global_novar / / "undefined" typeof global_fromfunc; / / "undefined"

In ES5 strict mode, undeclared variables (such as the two negative examples in the previous code snippet) throw an error when working.

Access to global objects (Access to the Global Object)

In the browser, global objects can be accessed anywhere in the code through the window property (unless you do something out of line, such as declaring a local variable named window). But in other environments, this convenient attribute may be called something else (or even not available in the program). If you need to access the global object under a window identifier that is not hard-coded, you can do the following at any level of function scope:

Var global = (function () {return this;} ())

This method can get the global object at any time, because it is called as a function in the function (not constructed by new), and the this always points to the global object. In fact, this disease does not apply to ECMAScript 5 strict mode, so when in strict mode, you have to take a different form. For example, if you are developing a JavaScript library, you can wrap your code in a real-time function and pass a reference to this from the global scope as an argument to your immediate function.

Single var form (Single var Pattern)

Using a single var statement at the top of a function is a useful form, with the following benefits:

◆ provides a single place to find all the local variables needed for the function.

◆ prevents logical errors used by variables before they are defined

◆ helps you remember declared global variables, so there are fewer global variables / / zxx: I'm a little dizzy here myself.

Less code in ◆ (type, pass value and one-line completion)

The single var form looks like this:

Function func () {var a = 1, b = 2, sum = a + b, myobject = {}, I, j; / / function body... }

You can declare multiple variables using a single var statement, separated by commas. It is good to initialize variables and initialize values at the same time. This prevents logic errors (the initial value of all uninitialized but declared variables is undefined) and increases the readability of the code. After you see the code, you can know the general purpose of these variables according to the initialized values, such as whether to use them as objects or as integers.

You can also do some practical work when declaring, such as sum = a + b in the previous code. Another example is that when you use a DOM (document object Model) reference, you can use a single var to specify the DOM reference as a local variable, as shown in the following code:

Function updateElement () {var el = document.getElementById ("result"), style = el.style; / / do something else using el and style.}

Pre-parsing: the problem of var dispersion (Hoisting: A Problem with Scattered vars)

In JavaScript, you can declare multiple var statements anywhere in a function, and they function as if they were declared at the top of the function, a behavior called hoisting (suspension / Top parsing / pre-parsing). When you use a variable and then redeclare it in a function soon, a logic error may occur. For JavaScript, as long as your variable is in the same scope (the same function), it is treated as declared, even if it is used before the var declaration. Look at the following example:

/ / counterexample myname = "global"; / / Global variable function func () {alert (myname); / / "undefined" var myname = "local"; alert (myname); / / "local"} func ()

In this example, you might think that the alert pop-up is "global" and the second pop-up is "loacl". This expectation is understandable because the myname is not declared at * alert, and the function must naturally look at the global variable myname, but it doesn't actually work that way. * the alert pops up "undefined" because the myname is treated as a local variable of the function (although it is declared later), and all variable declarations should be suspended to the top of the function. Therefore, to avoid this confusion, * * is to pre-declare all the variables you want to use.

The above code snippet might perform behavior like this:

Myname = "global"; / / global variable function func () {var myname; / / equivalent to-> var myname = undefined; alert (myname); / / "undefined" myname = "local"; alert (myname); / / "local"} func ()

For the sake of completeness, let's mention something slightly more complicated at the implementation level. Code processing is divided into two phases, the * phase is variables, function declarations, and parameter creation in normal format, which is a stage of parsing and entering context. The second phase is code execution, where function expressions and unqualified identifiers (declared variables) are created. However, for practical purposes, we adopt the concept of "hoisting", which is not defined in the ECMAScript standard and is usually used to describe behavior.

For cycle (for Loops)

In the for loop, you can loop through an array or an array of similar objects, such as arguments and HTMLCollection objects. The usual form of loop is as follows:

/ / second-best cyclic for (var I = 0; I

< myarray.length; i++) { // 使用myarray[i]做点什么 } 这种形式的循环的不足在于每次循环的时候数组的长度都要去获取下。这回降低你的代码,尤其当myarray不是数组,而是一个HTMLCollection对象的时候。 HTMLCollections指的是DOM方法返回的对象,例如: document.getElementsByName() document.getElementsByClassName() document.getElementsByTagName() 还有其他一些HTMLCollections,这些是在DOM标准之前引进并且现在还在使用的。有: document.images: 页面上所有的图片元素 document.links : 所有a标签元素 document.forms : 所有表单 document.forms[0].elements : 页面上***个表单中的所有域 集合的麻烦在于它们实时查询基本文档(HTML页面)。这意味着每次你访问任何集合的长度,你要实时查询DOM,而DOM操作一般都是比较昂贵的。 这就是为什么当你循环获取值时,缓存数组(或集合)的长度是比较好的形式,正如下面代码显示的: for (var i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做点什么 } 这样,在这个循环过程中,你只检索了一次长度值。 在所有浏览器下,循环获取内容时缓存HTMLCollections的长度是更快的,2倍(Safari3)到190倍(IE7)之间。//zxx:此数据貌似很老,仅供参考 注意到,当你明确想要修改循环中的集合的时候(例如,添加更多的DOM元素),你可能更喜欢长度更新而不是常量。 伴随着单var形式,你可以把变量从循环中提出来,就像下面这样: function looper() { var i = 0, max, myarray = []; // ... for (i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做点什么 } } 这种形式具有一致性的好处,因为你坚持了单一var形式。不足在于当重构代码的时候,复制和粘贴整个循环有点困难。例如,你从一个函数复制了一个循环到另一个函数,你不得不去确定你能够把i和max引入新的函数(如果在这里没有用的话,很有可能你要从原函数中把它们删掉)。 ***一个需要对循环进行调整的是使用下面表达式之一来替换i++。 ii = i + 1 i += 1 JSLint提示您这样做,原因是++和–-促进了"过分棘手(excessive trickiness)"。//zxx:这里比较难翻译,我想本意应该是让代码变得更加的棘手 如果你直接无视它,JSLint的plusplus选项会是false(默认是default)。 还有两种变化的形式,其又有了些微改进,因为: ◆ 少了一个变量(无max) ◆ 向下数到0,通常更快,因为和0做比较要比和数组长度或是其他不是0的东西作比较更有效率 //***种变化的形式: var i, myarray = []; for (i = myarray.length; i–-;) { // 使用myarray[i]做点什么 } //第二种使用while循环: var myarray = [], i = myarray.length; while (i–-) { // 使用myarray[i]做点什么 } 这些小的改进只体现在性能上,此外JSLint会对使用i–-加以抱怨。 for-in循环(for-in Loops) for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为"枚举"。 从技术上将,你可以使用for-in循环数组(因为JavaScript中数组也是对象),但这是不推荐的。因为如果数组对象已被自定义的功能增强,就可能发生逻辑错误。另外,在for-in中,属性列表的顺序(序列)是不能保证的。所以***数组使用正常的for循环,对象使用for-in循环。 有个很重要的hasOwnProperty()方法,当遍历对象属性的时候可以过滤掉从原型链上下来的属性。 思考下面一段代码: // 对象 var man = { hands: 2, legs: 2, heads: 1 }; // 在代码的某个地方 // 一个方法添加给了所有对象 if (typeof Object.prototype.clone === "undefined") { Object.prototype.clone = function () {}; } 在这个例子中,我们有一个使用对象字面量定义的名叫man的对象。在man定义完成后的某个地方,在对象原型上增加了一个很有用的名叫 clone()的方法。此原型链是实时的,这就意味着所有的对象自动可以访问新的方法。为了避免枚举man的时候出现clone()方法,你需要应用hasOwnProperty()方法过滤原型属性。如果不做过滤,会导致clone()函数显示出来,在大多数情况下这是不希望出现的。 // 1. // for-in 循环 for (var i in man) { if (man.hasOwnProperty(i)) { // 过滤 console.log(i, ":", man[i]); } } /* 控制台显示结果 hands : 2 legs : 2 heads : 1 */ // 2. // 反面例子: // for-in loop without checking hasOwnProperty() for (var i in man) { console.log(i, ":", man[i]); } /* 控制台显示结果 hands : 2 legs : 2 heads : 1 clone: function() */ 另外一种使用hasOwnProperty()的形式是取消Object.prototype上的方法。像是: for (var i in man) { if (Object.prototype.hasOwnProperty.call(man, i)) { // 过滤 console.log(i, ":", man[i]); } } 其好处在于在man对象重新定义hasOwnProperty情况下避免命名冲突。也避免了长属性查找对象的所有方法,你可以使用局部变量"缓存"它。 var i, hasOwn = Object.prototype.hasOwnProperty; for (i in man) { if (hasOwn.call(man, i)) { // 过滤 console.log(i, ":", man[i]); } } 严格来说,不使用hasOwnProperty()并不是一个错误。根据任务以及你对代码的自信程度,你可以跳过它以提高些许的循环速度。但是当你对当前对象内容(和其原型链)不确定的时候,添加hasOwnProperty()更加保险些。格式化的变化(通不过JSLint)会直接忽略掉花括号,把if语句放到同一行上。其优点在于循环语句读起来就像一个完整的想法(每个元素都有一个自己的属性"X",使用"X"干点什么): // 警告: 通不过JSLint检测 var i, hasOwn = Object.prototype.hasOwnProperty; for (i in man) if (hasOwn.call(man, i)) { // 过滤 console.log(i, ":", man[i]); } (不)扩展内置原型((Not) Augmenting Built-in Prototypes) 扩增构造函数的prototype属性是个很强大的增加功能的方法,但有时候它太强大了。 增加内置的构造函数原型(如Object(), Array(), 或Function())挺诱人的,但是这严重降低了可维护性,因为它让你的代码变得难以预测。使用你代码的其他开发人员很可能更期望使用内置的 JavaScript方法来持续不断地工作,而不是你另加的方法。 另外,属性添加到原型中,可能会导致不使用hasOwnProperty属性时在循环中显示出来,这会造成混乱。 因此,不增加内置原型是***的。你可以指定一个规则,仅当下面的条件均满足时例外: ◆ 可以预期将来的ECMAScript版本或是JavaScript实现将一直将此功能当作内置方法来实现。例如,你可以添加ECMAScript 5中描述的方法,一直到各个浏览器都迎头赶上。这种情况下,你只是提前定义了有用的方法。 ◆ 如果您检查您的自定义属性或方法已不存在——也许已经在代码的其他地方实现或已经是你支持的浏览器JavaScript引擎部分。 ◆ 你清楚地文档记录并和团队交流了变化。 如果这三个条件得到满足,你可以给原型进行自定义的添加,形式如下: if (typeof Object.protoype.myMethod !== "function") { Object.protoype.myMethod = function () { // 实现... }; } switch模式(switch Pattern) 你可以通过类似下面形式的switch语句增强可读性和健壮性: var inspect_me = 0, result = ''; switch (inspect_me) { case 0: result = "zero"; break; case 1: result = "one"; break; default: result = "unknown"; } 这个简单的例子中所遵循的风格约定如下: ◆ 每个case和switch对齐(花括号缩进规则除外) ◆ 每个case中代码缩进 ◆ 每个case以break清除结束 ◆ 避免贯穿(故意忽略break)。如果你非常确信贯穿是***的方法,务必记录此情况,因为对于有些阅读人而言,它们可能看起来是错误的。 ◆ 以default结束switch:确保总有健全的结果,即使无情况匹配。 避免隐式类型转换(Avoiding Implied Typecasting ) JavaScript的变量在比较的时候会隐式类型转换。这就是为什么一些诸如:false == 0 或 "" == 0 返回的结果是true。为避免引起混乱的隐含类型转换,在你比较值和表达式类型的时候始终使用===和!==操作符。 var zero = 0; if (zero === false) { // 不执行,因为zero为0, 而不是false } // 反面示例 if (zero == false) { // 执行了... } 还有另外一种思想观点认为==就足够了===是多余的。例如,当你使用typeof你就知道它会返回一个字符串,所以没有使用严格相等的理由。然而,JSLint要求严格相等,它使代码看上去更有一致性,可以降低代码阅读时的精力消耗。("==是故意的还是一个疏漏?") 避免(Avoiding) eval() 如果你现在的代码中使用了eval(),记住该咒语"eval()是魔鬼"。此方法接受任意的字符串,并当作JavaScript代码来处理。当有 问题的代码是事先知道的(不是运行时确定的),没有理由使用eval()。如果代码是在运行时动态生成,有一个更好的方式不使用eval而达到同样的目 标。例如,用方括号表示法来访问动态属性会更好更简单: // 反面示例 var property = "name"; alert(eval("obj." + property)); // 更好的 var property = "name"; alert(obj[property]); 使用eval()也带来了安全隐患,因为被执行的代码(例如从网络来)可能已被篡改。这是个很常见的反面教材,当处理Ajax请求得到的JSON 相应的时候。在这些情况下,***使用JavaScript内置方法来解析JSON相应,以确保安全和有效。若浏览器不支持JSON.parse(),你可 以使用来自JSON.org的库。 同样重要的是要记住,给setInterval(), setTimeout()和Function()构造函数传递字符串,大部分情况下,与使用eval()是类似的,因此要避免。在幕后,JavaScript仍需要评估和执行你给程序传递的字符串: // 反面示例 setTimeout("myFunc()", 1000); setTimeout("myFunc(1, 2, 3)", 1000); // 更好的 setTimeout(myFunc, 1000); setTimeout(function () { myFunc(1, 2, 3); }, 1000); 使用新的Function()构造就类似于eval(),应小心接近。这可能是一个强大的构造,但往往被误用。如果你绝对必须使用eval(),你 可以考虑使用new Function()代替。有一个小的潜在好处,因为在新Function()中作代码评估是在局部函数作用域中运行,所以代码中任何被评估的通过var 定义的变量都不会自动变成全局变量。另一种方法来阻止自动全局变量是封装eval()调用到一个即时函数中。 考虑下面这个例子,这里仅un作为全局变量污染了命名空间。 console.log(typeof un); // "undefined" console.log(typeof deux); // "undefined" console.log(typeof trois); // "undefined" var jsstring = "var un = 1; console.log(un);"; eval(jsstring); // logs "1" jsstring = "var deux = 2; console.log(deux);"; new Function(jsstring)(); // logs "2" jsstring = "var trois = 3; console.log(trois);"; (function () { eval(jsstring); }()); // logs "3" console.log(typeof un); // number console.log(typeof deux); // "undefined" console.log(typeof trois); // "undefined" 另一间eval()和Function构造不同的是eval()可以干扰作用域链,而Function()更安分守己些。不管你在哪里执行 Function(),它只看到全局作用域。所以其能很好的避免本地变量污染。在下面这个例子中,eval()可以访问和修改它外部作用域中的变量,这是 Function做不来的(注意到使用Function和new Function是相同的)。 (function () { var local = 1; eval("local = 3; console.log(local)"); // logs "3" console.log(local); // logs "3" }()); (function () { var local = 1; Function("console.log(typeof local);")(); // logs undefined }()); parseInt()下的数值转换(Number Conversions with parseInt()) 使用parseInt()你可以从字符串中获取数值,该方法接受另一个基数参数,这经常省略,但不应该。当字符串以"0″开头的时候就有可能会出问 题,例如,部分时间进入表单域,在ECMAScript 3中,开头为"0″的字符串被当做8进制处理了,但这已在ECMAScript 5中改变了。为了避免矛盾和意外的结果,总是指定基数参数。 var month = "06", year = "09"; month = parseInt(month, 10); year = parseInt(year, 10); 此例中,如果你忽略了基数参数,如parseInt(year),返回的值将是0,因为"09"被当做8进制(好比执行 parseInt( year, 8 )),而09在8进制中不是个有效数字。 替换方法是将字符串转换成数字,包括: +"08" // 结果是 8 Number("08") // 8 这些通常快于parseInt(),因为parseInt()方法,顾名思意,不是简单地解析与转换。但是,如果你想输入例如"08 hello",parseInt()将返回数字,而其它以NaN告终。 编码规范(Coding Conventions) 建立和遵循编码规范是很重要的,这让你的代码保持一致性,可预测,更易于阅读和理解。一个新的开发者加入这个团队可以通读规范,理解其它团队成员书写的代码,更快上手干活。 许多激烈的争论发生会议上或是邮件列表上,问题往往针对某些代码规范的特定方面(例如代码缩进,是Tab制表符键还是space空格键)。如果你是 你组织中建议采用规范的,准备好面对各种反对的或是听起来不同但很强烈的观点。要记住,建立和坚定不移地遵循规范要比纠结于规范的细节重要的多。 缩进(Indentation) 代码没有缩进基本上就不能读了。唯一糟糕的事情就是不一致的缩进,因为它看上去像是遵循了规范,但是可能一路上伴随着混乱和惊奇。重要的是规范地使用缩进。 一些开发人员更喜欢用tab制表符缩进,因为任何人都可以调整他们的编辑器以自己喜欢的空格数来显示Tab。有些人喜欢空格——通常四个,这都无所谓,只要团队每个人都遵循同一个规范就好了。这本书,例如,使用四个空格缩进,这也是JSLint中默认的缩进。 什么应该缩进呢?规则很简单——花括号里面的东西。这就意味着函数体,循环 (do, while, for, for-in),if,switch,以及对象字面量中的对象属性。下面的代码就是使用缩进的示例: function outer(a, b) { var c = 1, d = 2, inner; if (a >

B) {inner = function () {return {r: C-d};} else {inner = function () {return {r: C + d};};} return inner;}

Curly braces {} (Curly Braces)

Curly braces (also known as curly braces, the same below) should always be used, even when they are optional. Technically, curly braces are not needed if there is only one statement in in or for, but you should always use them, which makes the code more persistent and easier to update.

Imagine that you have a for loop with only one statement, and you can ignore curly braces without parsing errors.

/ / Bad instance for (var I = 0; I < 10; I + = 1) alert (I)

But what if, later, lines of code were added to the body loop?

/ / Bad instance for (var I = 0; I < 10; I + = 1) alert (I); alert (I + "is" + (I% 2?) "odd": "even"))

The second alert is already outside the loop, and indentation may deceive you. For long-term purposes, * * always use curly braces, that is, a line of code with a current value:

/ / A good instance for (var I = 0; I < 10; I + = 1) {alert (I);}

The if conditions are similar:

/ / Bad if (true) alert (1); else alert (2); / / good if (true) {alert (1);} else {alert (2);}

Position of the left curly bracket (Opening Brace Location)

Developers have different preferences for the location of the left brace-on the same line or on the next line.

If (true) {alert ("It's TRUE!");} / or if (true) {alert ("It's TRUE!");}

In this example, the benevolent see benevolence and the wise see wisdom, but there are also cases where different parentheses will have different behaviors. This is because the semicolon insertion mechanism (semicolon insertion mechanism)-JavaScript is not picky, and JavaScript will make it up for you when you choose not to use a semicolon to end a line of code. This behavior can cause annoyance, such as when you return the literal amount of the object and the left parenthesis is on the next line:

/ / warning: unexpected return value function func () {return / / the following code does not execute {name: "Batman"}}

You will be surprised if you want the function to return an object that contains the name property. Because of the implicit semicolon, the function returns undefined. The previous code is equivalent to:

/ / warning: unexpected return value function func () {return undefined; / / the following code does not execute {name: "Batman"}}

In short, always use curly braces and always put them on the same line as the previous statement:

Function func () {return {name: "Batman"};}

Note about semicolons: just like using curly braces, you should always use semicolons, even if they can be created implicitly by JavaScript parsers. This not only promotes more scientific and rigorous code, but also helps to solve doubts, as shown in the previous example.

Space (White Space)

The use of spaces also helps to improve the readability and consistency of the code. When writing English sentences, intervals are used after commas and periods. In JavaScript, you can follow the same logic to add intervals after list appearance expressions (equivalent to commas) and closing statements (as opposed to completing "ideas").

Suitable places to use spaces include:

The part separated by the semicolon of the ◆ for loop: for example, for (var I = 0; I < 10; I + = 1) {.}

Multivariables initialized in the ◆ for loop (I and max): for (var I = 0, max = 10; I < max; I + = 1) {.}

◆ separates the comma of the array items after: var a = [1,2,3]

After the ◆ object attribute comma and the colon that separates the attribute name from the attribute value: var o = {a: 1, b: 2}

◆ qualifies function parameters: myFunc (a, b, c)

Before the curly braces declared by the ◆ function: function myFunc () {}

◆ anonymous function expression function followed by: var myFunc = function () {}

Using spaces to separate all operators and operands is another good use, which means that spaces are required before and after +, -, *, =, =,! = =, & &, |, + =, etc.

/ / loose and consistent spacing / / make the code more readable / / make it more "breathable" var d = 0, a = b + 1; if (a & b & & c) {d = a% c; a + = d;} / / negative examples / / missing or different spacing / / make the code confusing var d = 0, a = b + 1 If (a&&b&&c) {dicia% c; axiom = d;}

* A space to pay attention to-curly braces spacing. * use spaces:

The front ({) of the left curly braces of ◆ functions, if-else statements, loops, and literals of objects

Closing curly braces between ◆ else or while (})

One deficiency in the use of spaces is that it increases the size of the file, but compression does not have this problem.

One aspect of code readability that is often overlooked is the use of vertical spaces. You can use blank lines to separate code units, just as paragraph separation is used in literature.

Naming Convention (Naming Conventions)

Another way to make your code more predictable and maintainable is to adopt naming conventions. This means that you need to name your variables and functions in the same form.

Here are some suggested naming conventions that you can use as is or adjust according to your preferences. Similarly, following the specification is more important than what the specification is.

Write the constructor in uppercase letters (Capitalizing Constructors)

JavaScript does not have a class, but it does have a constructor called by new:

Var adam = new Person ()

Because the constructor is still just a function, just looking at the function name can help tell you whether it should be a constructor or a normal function.

The first letter uppercase is suggestive when naming constructors, and functions and methods that are named in lowercase should not use new calls:

Function MyConstructor () {...} function myFunction () {...}

Separated words (Separating Words)

When your variable or function name has multiple words, the separation of words follows a uniform specification, and there is a common practice called "Camel nomenclature", which is lowercase words with the first letter of each word capitalized.

For constructors, you can use large hump naming (upper camel case), such as MyConstructor (). For function and method names, you can use small hump naming (lower camel case), such as myFunction (), calculateArea (), and getFirstName ().

What if the variable is not a function? Developers usually use hump naming, but another way is to connect all words with lowercase underscores: for example, first_name, favorite_bands, and old_company_name, which helps you visually distinguish between functions and other identities-prototypes and objects.

Both the properties and methods of ECMAScript use Camel tokens, although multi-word attribute names are rare (lastIndex and ignoreCase properties of regular expression objects).

Other naming forms (Other Naming Patterns)

Sometimes developers use naming conventions to complement or replace language features.

For example, there are no methods to define constants in JavaScript (although there are some built-in methods like Number and MAX_VALUE), so developers use the specification of all word capitalization to name variables that will not change in the program's life cycle, such as:

/ / Precious constant. Only var PI = 3.14,800 MAX_WIDTH can be viewed from afar.

There is another convention of complete capitalization: global variable names are all uppercase. Naming global variables in all capitals reinforces the practice of reducing the number of global variables while making them easy to distinguish.

Another way to use specifications to simulate functionality is private members. Although it is possible to be truly private in JavaScript, developers find it easier to use only an underscore prefix to represent a private property or method. Consider the following example:

Var person = {getName: function () {return this._getFirst () +'+ this._getLast ();}, _ getFirst: function () {/ /...}, _ getLast: function () {/ /...}}

In this case, getName () represents a public method, a partially stable API. While _ getFirst () and _ getLast () indicate private. They are still normal public methods, but use the underscore prefix to warn users of person objects that these methods are not guaranteed to work in the next version and cannot be used directly. Note that JSLint has some ununderlined prefixes unless you set the noman option to: false.

Here are some common _ private specifications:

◆ uses underscores to indicate private ownership, such as name_ and getElements_ ()

◆ uses an underscore prefix table _ protected (protection) attribute, and two underscore prefixes represent the _ _ private (private) attribute

Some of the built-in variable attributes in ◆ Firefox are not part of the technical part of the language and are represented by two front underscores and two back underscores, such as _ _ proto__ and _ _ parent__.

Comments (Writing Comments)

You have to comment on your code, even if no one else touches it like you do. Usually, when you delve into a problem, you know exactly what the code is for, but when you come back a week later, it must take a lot of brain cells to figure out how it works.

Obviously, comments can't go to extremes: each individual variable or a separate line. However, you should usually record all functions, their parameters and return values, or any unusual techniques and methods. Think that annotations can give future readers of your code a lot of hints; what readers need is (don't read too much) just comments and function property names to understand your code. For example, when you have five or six lines of programs to perform specific tasks, if you provide a description of the purpose of the code and why it is here, the reader can skip this detail directly. There is no hard and fast rule that some parts of the code (such as regular expressions) may have more comments than the code.

The most important habit, but also the most difficult to follow, is to keep comments up-to-date, because outdated comments are more misleading than no comments.

After reading the above, have you mastered the basic points of writing high-quality JavaScript code? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report