提交 c7165998 编写于 作者: A almighty 提交者: NEEN

!18 刷新编程规范

* ISSUE:#I1UOOT 刷新编程规范
* update contribute/OpenHarmony-JavaScript-coding-style-guide.md.
上级 e5a642df
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
#### 规则1.2 命名尽量少用缩写,除非是常见词或者业务线的领域词汇。比如:`context`可以简写成`ctx`,`request`可简写成`req`,`response`可简写成`resp`。 #### 规则1.2 命名尽量少用缩写,除非是常见词或者业务线的领域词汇。比如:`context`可以简写成`ctx`,`request`可简写成`req`,`response`可简写成`resp`。
**说明:**完整的单词拼写可以避免不必要的阅读障碍。 **说明:** 完整的单词拼写可以避免不必要的阅读障碍。
**例外:**循环语种中可以使用`i``j`循环条件变量名。 **例外:** 循环语种中可以使用`i``j`循环条件变量名。
#### 规则1.3 类名、枚举名、命名空间名采用`upperCamelCase`风格。 #### 规则1.3 类名、枚举名、命名空间名采用`upperCamelCase`风格。
...@@ -124,7 +124,7 @@ function hasNext() {} ...@@ -124,7 +124,7 @@ function hasNext() {}
#### 规则2.1 采用2个空格缩进,禁止使用`tab`字符 #### 规则2.1 采用2个空格缩进,禁止使用`tab`字符
**说明:**只允许使用空格(space)进行缩进,每次缩进为2个空格。不允许使用Tab 符进行缩进。 **说明:** 只允许使用空格(space)进行缩进,每次缩进为2个空格。不允许使用Tab 符进行缩进。
**正例:** **正例:**
...@@ -165,9 +165,9 @@ function render(container, dataSource) { ...@@ -165,9 +165,9 @@ function render(container, dataSource) {
#### 规则2.2 行宽不超过`120`个字符 #### 规则2.2 行宽不超过`120`个字符
**说明:**建议每行字符数不要超过 120 个。如果超过120个字符,请选择合理的方式进行换行。 **说明:** 建议每行字符数不要超过 120 个。如果超过120个字符,请选择合理的方式进行换行。
**例外:**如果一行注释包含了超过120 个字符的命令或URL,则可以保持一行,以方便复制、粘贴和通过grep查找; 预处理的 error 信息在一行便于阅读和理解,即使超过 120 个字符。 **例外:** 如果一行注释包含了超过120 个字符的命令或URL,则可以保持一行,以方便复制、粘贴和通过grep查找; 预处理的 error 信息在一行便于阅读和理解,即使超过 120 个字符。
#### 规则3.3 大括号的使用须遵循约定: #### 规则3.3 大括号的使用须遵循约定:
...@@ -245,7 +245,7 @@ switch(condition) { ...@@ -245,7 +245,7 @@ switch(condition) {
#### 规则2.7 表达式换行须保持一致性,运算符放行末。 #### 规则2.7 表达式换行须保持一致性,运算符放行末。
**说明:**较长的表达式,不满足行宽要求时,需要在适当的位置进行换行。一般在较低优先级运算符或连接符后面阶段,运算符或连接符放行末。运算符、连接符放在行末,表示“未结束,后续还有”。 **说明:** 较长的表达式,不满足行宽要求时,需要在适当的位置进行换行。一般在较低优先级运算符或连接符后面阶段,运算符或连接符放行末。运算符、连接符放在行末,表示“未结束,后续还有”。
**正例:** **正例:**
...@@ -291,7 +291,7 @@ let pointY = 0; ...@@ -291,7 +291,7 @@ let pointY = 0;
#### 规则2.9 空格应该突出关键字和重要信息,避免不必要的空格。 #### 规则2.9 空格应该突出关键字和重要信息,避免不必要的空格。
**说明:**空格可以减低代码密度,增加代码的可读性。总体规则如下: **说明:** 空格可以减低代码密度,增加代码的可读性。总体规则如下:
1. `if``elseif``else``switch``while``for`等关键字之后加空格; 1. `if``elseif``else``switch``while``for`等关键字之后加空格;
2. 小括号内部两侧不加空格; 2. 小括号内部两侧不加空格;
...@@ -338,7 +338,7 @@ console.log(message); ...@@ -338,7 +338,7 @@ console.log(message);
#### 规则3.1 声明变量时须使用`var`、`let`或`const`关键字进行声明,避免变量暴露到全局作用域上。 #### 规则3.1 声明变量时须使用`var`、`let`或`const`关键字进行声明,避免变量暴露到全局作用域上。
**说明:**不使用`var``let``const`关键字声明变量,会导致将变量暴露到全局作用域上,这样可能会覆盖全局作用域上的同名变量,进而引发GC无法有效回收内存的问题;另外,当变量中包含敏感信息时,暴露到全局作用域可能会导致信息泄露问题。另外,**尽量对所有的引用使用`const`,不要使用 `var`;如果你一定需要可变动的引用,使用 `let` 代替 `var`**。因为`const``let`的作用域更小,写代码更容易控制;const可确保无法对引用重新赋值,const引用的指针不可变,重新赋值会报错,避免了不小心的重新赋值给覆盖了。 **说明:** 不使用`var``let``const`关键字声明变量,会导致将变量暴露到全局作用域上,这样可能会覆盖全局作用域上的同名变量,进而引发GC无法有效回收内存的问题;另外,当变量中包含敏感信息时,暴露到全局作用域可能会导致信息泄露问题。另外,**尽量对所有的引用使用`const`,不要使用 `var`;如果你一定需要可变动的引用,使用 `let` 代替 `var`**。因为`const``let`的作用域更小,写代码更容易控制;const可确保无法对引用重新赋值,const引用的指针不可变,重新赋值会报错,避免了不小心的重新赋值给覆盖了。
**反例:** **反例:**
...@@ -375,7 +375,7 @@ console.log(url); //报错:Uncaught ReferenceError: url is not defined ...@@ -375,7 +375,7 @@ console.log(url); //报错:Uncaught ReferenceError: url is not defined
#### 规则3.2 函数块内须使用函数表达式声明函数 #### 规则3.2 函数块内须使用函数表达式声明函数
**说明:**虽然很多 JS 引擎都支持块内声明函数,但它不属于 ECMAScript规范,各个浏览器糟糕的实现相互不兼容,有些也与未来 ECMAScript草案相违背。另外,ECMAScript5不支持块作用域,对于所有的控制流都不是独立的作用域,其内部声明的变量或者函数都是在其父函数或者脚本的作用域中,导致块内函数或者变量的声明会存在覆盖现象。如果确实需要在块中定义函数,应该使用函数表达式来初始化。 **说明:** 虽然很多 JS 引擎都支持块内声明函数,但它不属于 ECMAScript规范,各个浏览器糟糕的实现相互不兼容,有些也与未来 ECMAScript草案相违背。另外,ECMAScript5不支持块作用域,对于所有的控制流都不是独立的作用域,其内部声明的变量或者函数都是在其父函数或者脚本的作用域中,导致块内函数或者变量的声明会存在覆盖现象。如果确实需要在块中定义函数,应该使用函数表达式来初始化。
**反例:** **反例:**
...@@ -418,7 +418,7 @@ bar("hotel"); // 正确输出"hotel foo 1" ...@@ -418,7 +418,7 @@ bar("hotel"); // 正确输出"hotel foo 1"
#### 规则3.3 禁止封装基本类型 #### 规则3.3 禁止封装基本类型
**说明:**JavaScript中有五种基本数据类型:Undefined、Null、Boolean、Number和String。基本数据类型的值是不可更改的。JavaScript中使用基本数据类型对象只是值,不包含器封装对象的方法和属性,在不需要使用属性和方法的时候,不需要使用其封装类型。 **说明:** JavaScript中有五种基本数据类型:Undefined、Null、Boolean、Number和String。基本数据类型的值是不可更改的。JavaScript中使用基本数据类型对象只是值,不包含器封装对象的方法和属性,在不需要使用属性和方法的时候,不需要使用其封装类型。
**反例:** **反例:**
...@@ -440,7 +440,7 @@ if (isShow) { ...@@ -440,7 +440,7 @@ if (isShow) {
#### 规则3.4 禁止使用`with` #### 规则3.4 禁止使用`with`
**说明:**使用 with让你的代码在语义上变得不清晰,因为with的对象,可能会与局部变量产生冲突,从而改变程序原本的用义。 **说明:** 使用 with让你的代码在语义上变得不清晰,因为with的对象,可能会与局部变量产生冲突,从而改变程序原本的用义。
**反例:** **反例:**
...@@ -454,7 +454,7 @@ with(foo) { ...@@ -454,7 +454,7 @@ with(foo) {
#### 规则3.5 `this`仅可在对象构造函数、方法、闭包中使用 #### 规则3.5 `this`仅可在对象构造函数、方法、闭包中使用
**说明:**在JavaScript里面,this指针代表的是执行当前代码的对象的所有者。this具有特殊的语义: **说明:** 在JavaScript里面,this指针代表的是执行当前代码的对象的所有者。this具有特殊的语义:
+ 全局对象(大多数情况下) + 全局对象(大多数情况下)
+ 调用者的作用域(使用eval时) + 调用者的作用域(使用eval时)
...@@ -485,7 +485,7 @@ console.log(Counter.getValue()); //输出:1 ...@@ -485,7 +485,7 @@ console.log(Counter.getValue()); //输出:1
#### 规则3.6 禁止使用IE下的条件注释 #### 规则3.6 禁止使用IE下的条件注释
**说明:**在IE下使用`\@cc_on`语句或使用`\@if``\@set`语句可以激活条件编译。尽管可以通过注释来兼容IE以外的浏览器,但它妨碍自动化工具的执行,因为在运行时,它们会改变JavaScript 语法树。 **说明:** 在IE下使用`\@cc_on`语句或使用`\@if``\@set`语句可以激活条件编译。尽管可以通过注释来兼容IE以外的浏览器,但它妨碍自动化工具的执行,因为在运行时,它们会改变JavaScript 语法树。
**反例:** **反例:**
...@@ -502,7 +502,7 @@ var f = function () { ...@@ -502,7 +502,7 @@ var f = function () {
#### 规则3.7 禁止修改内置对象的原型 #### 规则3.7 禁止修改内置对象的原型
**说明:**内置对象作为一套公共接口,具有约定俗成的行为方式,修改其原型,可能破坏接口语义,或导致调试时的诡异现象。 **说明:** 内置对象作为一套公共接口,具有约定俗成的行为方式,修改其原型,可能破坏接口语义,或导致调试时的诡异现象。
**反例:** **反例:**
...@@ -514,7 +514,7 @@ console.log(aar.indexOf(2)); // 输出:-1 ...@@ -514,7 +514,7 @@ console.log(aar.indexOf(2)); // 输出:-1
#### 规则3.8 禁止直接使用`Object.prototype`的内置属性 #### 规则3.8 禁止直接使用`Object.prototype`的内置属性
**说明:**ECMAScript5.1新增了`Object.create`,它创建一个新对象,使用现有的对象来提供新创建的对象的proto。`Object.create(null)`是用于创建用作map的对象的常用模式。当该对象具有`Object.prototype`同名的属性时,可能会导致意外行为或漏洞。例如,web服务器解析来自客户端的JSON输入并且使用`hasOwnProperty`直接调用生成的对象是不安全的,因为恶意客户端可能会发送类似的JSON值`'{ "hasOwnProperty": 1 }'` 并导致服务器崩溃。 **说明:** ECMAScript5.1新增了`Object.create`,它创建一个新对象,使用现有的对象来提供新创建的对象的proto。`Object.create(null)`是用于创建用作map的对象的常用模式。当该对象具有`Object.prototype`同名的属性时,可能会导致意外行为或漏洞。例如,web服务器解析来自客户端的JSON输入并且使用`hasOwnProperty`直接调用生成的对象是不安全的,因为恶意客户端可能会发送类似的JSON值`'{ "hasOwnProperty": 1 }'` 并导致服务器崩溃。
**反例:** **反例:**
...@@ -568,11 +568,11 @@ var func2 = function(a, b) { ...@@ -568,11 +568,11 @@ var func2 = function(a, b) {
#### 建议3.11 在使用原型`prototype`实现继承时,尽量使用现有稳定的库方法而非自行实现 #### 建议3.11 在使用原型`prototype`实现继承时,尽量使用现有稳定的库方法而非自行实现
**说明:**多级原型结构是指JavaScript中的继承关系。当定义一个D类,且把B类作为其原型,那么就获得了一个多级原型结构。这些原型结构会变得很复杂。使用现有的稳定的库方法如`the Closure`库的`goog.inherits()`或其他类似的函数,可避免不必要的编码失误,将是更好的选择。 **说明:** 多级原型结构是指JavaScript中的继承关系。当定义一个D类,且把B类作为其原型,那么就获得了一个多级原型结构。这些原型结构会变得很复杂。使用现有的稳定的库方法如`the Closure`库的`goog.inherits()`或其他类似的函数,可避免不必要的编码失误,将是更好的选择。
#### 建议3.12 定义类时,应在原型下定义方法,在构造方法内定义属性 #### 建议3.12 定义类时,应在原型下定义方法,在构造方法内定义属性
**说明:**JavaScript中有多种方法可以给构造函数添加方法或成员,但是使用原型定义方法,可以降低内存占用,提高运行效率。 **说明:** JavaScript中有多种方法可以给构造函数添加方法或成员,但是使用原型定义方法,可以降低内存占用,提高运行效率。
**反例:** **反例:**
...@@ -592,7 +592,7 @@ Animals.prototype.walk = function() {}; ...@@ -592,7 +592,7 @@ Animals.prototype.walk = function() {};
#### 建议3.13 使用闭包时,应避免构成循环引用,导致内存泄露 #### 建议3.13 使用闭包时,应避免构成循环引用,导致内存泄露
**说明:**JavaScript是一种垃圾收集式语言,其对象的内存是根据对象的创建分配给该对象的,并且会在没有对该对象的引用时由浏览器收回。JavaScript的垃圾收集机制本身并没有问题,但浏览器在为DOM对象分配和恢复内存的方式上有些出入。IE和Firefox均使用引用计数来为DOM对象处理内存。在引用计数系统中,每个所引用的对象都会保留一个计数,以获悉有多少对象正在引用它。如果计数为零,那么该对象就会被销毁,其占用的内存也会返回给堆。虽然这种解决方案总的来说还算有效,但是在循环引用方面却存在一些盲点。 当两个对象互相引用时,就构成了循环引用,其中对象的引用计数值都被赋为1。在纯垃圾收集系统中,循环引用问题不大:如果涉及的两个对象中有一个对象被任何其他对象引用,那么这两个对象都将被垃圾收集。而在引用计数系统中,这两个对象都不能被销毁,原因是引用计数永远不能为0。在同时使用了垃圾收集和引用计数的混合系统中,将会发生泄漏,因为系统不能正确识别循环引用。在这种情况下,DOM对象和JavaScript对象均不能被销毁。 循环引用很容易创建。在JavaScript最为方便的编程结构之一——闭包中,循环引用尤其突出。闭包会持有其外部作用域(包括局部变量、参数及方法)的引用,当闭包本身又被作用域成员(常见于DOM对象)持有时便构成循环引用,进一步导致内存泄露。 **说明:** JavaScript是一种垃圾收集式语言,其对象的内存是根据对象的创建分配给该对象的,并且会在没有对该对象的引用时由浏览器收回。JavaScript的垃圾收集机制本身并没有问题,但浏览器在为DOM对象分配和恢复内存的方式上有些出入。IE和Firefox均使用引用计数来为DOM对象处理内存。在引用计数系统中,每个所引用的对象都会保留一个计数,以获悉有多少对象正在引用它。如果计数为零,那么该对象就会被销毁,其占用的内存也会返回给堆。虽然这种解决方案总的来说还算有效,但是在循环引用方面却存在一些盲点。 当两个对象互相引用时,就构成了循环引用,其中对象的引用计数值都被赋为1。在纯垃圾收集系统中,循环引用问题不大:如果涉及的两个对象中有一个对象被任何其他对象引用,那么这两个对象都将被垃圾收集。而在引用计数系统中,这两个对象都不能被销毁,原因是引用计数永远不能为0。在同时使用了垃圾收集和引用计数的混合系统中,将会发生泄漏,因为系统不能正确识别循环引用。在这种情况下,DOM对象和JavaScript对象均不能被销毁。 循环引用很容易创建。在JavaScript最为方便的编程结构之一——闭包中,循环引用尤其突出。闭包会持有其外部作用域(包括局部变量、参数及方法)的引用,当闭包本身又被作用域成员(常见于DOM对象)持有时便构成循环引用,进一步导致内存泄露。
**反例:** **反例:**
...@@ -623,7 +623,7 @@ function createHandler(a, b) { ...@@ -623,7 +623,7 @@ function createHandler(a, b) {
#### 建议3.14 警惕JavaScript的浮点数 #### 建议3.14 警惕JavaScript的浮点数
**说明:**JavaScript具有单一数字类型:`IEEE 754`双精度浮点数。拥有单一数字类型是JavaScript的最佳功能之一。多种数字类型可能是复杂性,混淆和错误的根源。但是,二进制浮点类型有一个最大的缺点是,它不能准确地表示小数部分,会导致让人意外的精度问题,见下面示例。 **说明:** JavaScript具有单一数字类型:`IEEE 754`双精度浮点数。拥有单一数字类型是JavaScript的最佳功能之一。多种数字类型可能是复杂性,混淆和错误的根源。但是,二进制浮点类型有一个最大的缺点是,它不能准确地表示小数部分,会导致让人意外的精度问题,见下面示例。
示例代码1: 示例代码1:
...@@ -688,7 +688,7 @@ console.log(sum2); // 输出:0.6。所以对于二进制浮点数,(a + b) + ...@@ -688,7 +688,7 @@ console.log(sum2); // 输出:0.6。所以对于二进制浮点数,(a + b) +
#### 建议3.15 不要使用可变参数的Array构造函数说 #### 建议3.15 不要使用可变参数的Array构造函数说
**说明:**通常不鼓励使用构造函数`new Array`的方法来构造新数组,因为当构造函数只有一个参数的时候,可能会导致意外情况,另外Array的全局定义也可能被重新修改,所以提倡使用数组文字表示法来创建数组,也就是`[]`表示法。 **说明:** 通常不鼓励使用构造函数`new Array`的方法来构造新数组,因为当构造函数只有一个参数的时候,可能会导致意外情况,另外Array的全局定义也可能被重新修改,所以提倡使用数组文字表示法来创建数组,也就是`[]`表示法。
**反例:** **反例:**
```javascript ```javascript
...@@ -715,7 +715,7 @@ const arr4 = []; ...@@ -715,7 +715,7 @@ const arr4 = [];
#### 规则3.16 构建字符串时,优先使用字符串模板而不是字符串链接。 #### 规则3.16 构建字符串时,优先使用字符串模板而不是字符串链接。
**说明:**模板字符串表达更简洁,更具可读性。 **说明:** 模板字符串表达更简洁,更具可读性。
**反例:** **反例:**
......
...@@ -122,7 +122,7 @@ GetTotalCount() // OK ...@@ -122,7 +122,7 @@ GetTotalCount() // OK
### <a name="r1-2"></a>规则1.2 全局变量应增加 'g_' 前缀,函数内静态变量命名不需要加特殊前缀 ### <a name="r1-2"></a>规则1.2 全局变量应增加 'g_' 前缀,函数内静态变量命名不需要加特殊前缀
全局变量是应当尽量少使用的,使用时应特别注意,所以加上前缀用于视觉上的突出,促使开发人员对这些变量的使用更加小心。 全局变量应当尽量少使用,使用时应特别注意,所以加上前缀用于视觉上的突出,促使开发人员对这些变量的使用更加小心。
全局静态变量命名与全局变量相同,函数内的静态变量命名与普通局部变量相同。 全局静态变量命名与全局变量相同,函数内的静态变量命名与普通局部变量相同。
```c ```c
...@@ -572,7 +572,7 @@ for (i = 0; i < row; i++) { ...@@ -572,7 +572,7 @@ for (i = 0; i < row; i++) {
## <a name="c2-11"></a>初始化 ## <a name="c2-11"></a>初始化
初始化包括结构体、联合体及数组的初始化 初始化包括结构体、联合体及数组的初始化
### <a name="r2-10"></a>规则2.10 初始化换行时要有缩进,或进行合理对齐 ### <a name="r2-10"></a>规则2.10 初始化换行时要有缩进,或进行合理对齐
...@@ -951,9 +951,6 @@ int bar = 200; /* 放右边的注释 */ ...@@ -951,9 +951,6 @@ int bar = 200; /* 放右边的注释 */
这里说的注释掉代码,包括用 /\* \*/ 和 //,还包括 #if 0, #ifdef NEVER_DEFINED 等等。 这里说的注释掉代码,包括用 /\* \*/ 和 //,还包括 #if 0, #ifdef NEVER_DEFINED 等等。
在版本开发阶段,可以使用此类注释用于突出标注;交付前应该全部处理并删除掉。
### <a name="a3-1"></a>建议3.1 case语句块结束时如果不加break/return,需要有注释说明(fall-through) ### <a name="a3-1"></a>建议3.1 case语句块结束时如果不加break/return,需要有注释说明(fall-through)
有时候需要对多个case标签做相同的事情,case语句在结束不加break或return,直接执行下一个case标签中的语句,这在C语法中称之为"fall-through"。 有时候需要对多个case标签做相同的事情,case语句在结束不加break或return,直接执行下一个case标签中的语句,这在C语法中称之为"fall-through"。
...@@ -1066,7 +1063,7 @@ static void Bar(void) ...@@ -1066,7 +1063,7 @@ static void Bar(void)
头文件循环依赖,指 a.h 包含 b.h,b.h 包含 c.h,c.h 包含 a.h, 导致任何一个头文件修改,都导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。 头文件循环依赖,指 a.h 包含 b.h,b.h 包含 c.h,c.h 包含 a.h, 导致任何一个头文件修改,都导致所有包含了a.h/b.h/c.h的代码全部重新编译一遍。
而如果是单向依赖,如a.h包含b.h,b.h包含c.h,而c.h不包含任何头文件,则修改a.h不会导致包含了b.h/c.h的源代码重新编译。 而如果是单向依赖,如a.h包含b.h,b.h包含c.h,而c.h不包含任何头文件,则修改a.h不会导致包含了b.h/c.h的源代码重新编译。
头文件循环依赖直接体现了架构设计上的不合理,可通过优化架构去避免。 头文件循环依赖直接体现了架构设计上的不合理,可通过架构优化来避免。
### <a name="r4-4"></a>规则4.2 头文件必须编写#define保护,防止重复包含 ### <a name="r4-4"></a>规则4.2 头文件必须编写#define保护,防止重复包含
...@@ -1433,7 +1430,7 @@ int OtherFunc(void) ...@@ -1433,7 +1430,7 @@ int OtherFunc(void)
#define ASSERT(x) do { \ #define ASSERT(x) do { \
if (!(x)) { \ if (!(x)) { \
printk(KERN_EMERG "assertion failed %s: %d: %s\n", \ printk(KERN_EMERG "assertion failed %s: %d: %s\n", \
__FILE__, __LINE__, #x); \ __FILE__, __LINE__, #x); \
BUG(); \ BUG(); \
} \ } \
} while (0) } while (0)
...@@ -1977,8 +1974,3 @@ unsigned short int exam; ...@@ -1977,8 +1974,3 @@ unsigned short int exam;
ch = -1; ch = -1;
exam = ch; // Bad: 编译器不产生告警,此时exam为0xFFFF。 exam = ch; // Bad: 编译器不产生告警,此时exam为0xFFFF。
``` ```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册