Google JavaScript样式指南

1简介
1.1术语说明
1.2指南说明
2源文件基础知识
2.1文件名
2.2文件编码:UTF-8
2.3特殊字符
3源文件结构
3.1许可或版权信息(如果有)
3.2 @fileoverview JSDoc,如果存在的话
3.3 goog.module语句
3.4 goog.require语句
3.5文件的实现
4格式化
4.1大括号
4.2块缩进:+2个空格
4.3声明
4.4柱限:80
4.5换行
4.6空白
4.7分组括号:推荐
4.8评论
5语言功能
5.1局部变量声明
5.2数组文字
5.3对象文字
5.4课程
5.5功能
5.6字符串文字
5.7数字文字
5.8控制结构
5.9这个
5.10不允许的功能
6命名
6.1所有标识符共有的规则
6.2按标识符类型的规则
6.3 Camel案例:已定义
7 JSDoc
7.1一般表格
7.2降价
7.3 JSDoc标签
7.4换行
7.5顶级/文件级注释
7.6课堂评论
7.7枚举和typedef注释
7.8方法和功能注释
7.9财产评论
7.10输入注释
7.11可见性注释
8政策
8.1 Google风格未指定的问题:保持一致!
8.2编译器警告
8.3弃用
8.4不适用于Google风格的代码
8.5本地风格规则
8.6生成的代码:大多数是免除的
9附录
9.1 JSDoc标记引用
9.2常被误解的风格规则
9.3与风格相关的工具
9.4传统平台的例外情况

1简介

本文档用作JavaScript编程语言中Google源代码编码标准的完整定义。JavaScript源文件被描述为Google风格,当且仅当它符合此处的规则时。

与其他编程风格指南一样,所涉及的问题不仅包括格式化的美学问题,还包括其他类型的约定或编码标准。但是,本文档主要关注我们普遍遵循的严格规则,并避免提供不明确可执行的建议(无论是通过人工还是工具)。

1.1术语说明

在本文件中,除非另有说明:

  1. 术语注释总是指实现注释。我们不使用文档注释这一短语,而是使用常用术语“JSDoc”来表示人类可读的文本和机器可读的注释 /** … */

  2. 使用短语时,本样式指南使用RFC 2119术语必须, 不得应该不应该,也可以。术语偏好和 避免分别对应应该应该对应。命令性和陈述性陈述是规定性的,并且必须符合。

其他术语说明将在整个文件中偶尔出现。

1.2指南说明

本文档中的示例代码是非规范性的。也就是说,虽然示例是Google风格,但它们可能并没有说明代表代码的唯一时尚方式。在示例中进行的可选格式选择不得作为规则强制执行。

2源文件基础知识

2.1文件名

文件名必须全部小写,并且可以包含下划线(_)或短划线(-),但不包含其他标点符号。遵循项目使用的约定。文件名的扩展名必须是.js

2.2文件编码:UTF-8

源文件以UTF-8编码。

2.3特殊字符

2.3.1空白字符

除了行终止符序列之外,ASCII水平空格字符(0x20)是唯一出现在源文件中任何位置的空白字符。这意味着

  1. 字符串文字中的所有其他空白字符都被转义,并且

  2. 制表符用于缩进。

2.3.2特殊转义序列

对于具有特殊的转义序列(任何字符\'\"\\\b, \f\n\r\t\v),该序列使用,而不是对应的数字逃逸(例如\x0a\u000a\u{a})。传统的八进制转义从未使用过。

2.3.3非ASCII字符

对于剩余的非ASCII字符,使用实际的Unicode字符(例如)或等效的十六进制或Unicode转义(例如\u221e),这取决于哪些使代码更易于阅读和理解

提示:在Unicode转义情况下,有时即使使用实际的Unicode字符,解释性注释也会非常有用。

讨论
const units = 'μs';最佳:即使没有评论也完全清楚。
const units = '\u03bcs'; // 'μs'允许,但没有理由这样做。
const units = '\u03bcs'; // Greek letter mu, 's'允许,但尴尬,容易出错。
const units = '\u03bcs';差:读者不知道这是什么。
return '\ufeff' + content; // byte order mark好:对不可打印的字符使用转义,并在必要时进行注释。

提示:由于担心某些程序可能无法正确处理非ASCII字符,因此不要让代码的可读性降低。如果发生这种情况,那些程序就会被破坏,必须修复它们。

3源文件结构

源文件按顺序包含:

  1. 许可证或版权信息(如果有)
  2. @fileoverview JSDoc,如果存在的话
  3. goog.module 声明
  4. goog.require 声明
  5. 该文件的实现

除了文件的实现之外,正好有一个空行用于分隔存在的每个部分,其前面可能有1或2个空行。

如果许可或版权信息属于文件,则属于此处。

3.2 @fileoverviewJSDoc,如果存在的话

有关格式规则,请参见7.5顶级/文件级注释。

3.3 goog.module声明

所有文件必须goog.module在一行中只声明一个名称:包含goog.module声明的行不得包装,因此是80列限制的例外。

goog.module的整个参数是定义命名空间的。它是包名称(反映代码所在目录结构片段的标识符),以及它定义连接到结尾的主类/枚举/接口。

goog.module( 'search.urlHistory.UrlHistoryService');

3.3.1层次结构

模块命名空间可能永远不会被命名为另一个模块命名空间的直接子节点。

非法:

goog.module( 'foo.bar'); //'foo.bar.qux'会好的
goog.module( 'foo.bar.baz');

目录层次结构反映了命名空间层次结构,因此深层嵌套子节点是更高级别父目录的子目录。请注意,这意味着“父”命名空间组的所有者必须知道所有子命名空间,因为它们存在于同一目录中。

3.3.2 goog.setTestOnly

单个goog.module语句可以选择性地跟随对goog.setTestOnly()的调用。

3.3.3 goog.module.declareLegacyNamespace

单个goog.module语句可以选择性地跟随调用 goog.module.declareLegacyNamespace();goog.module.declareLegacyNamespace()尽可能避免 。

例:

goog.module( 'my.test.helpers');
goog.module.declareLegacyNamespace();
goog.setTestOnly();

goog.module.declareLegacyNamespace存在是为了简化从传统的基于对象层次结构的命名空间的转换,但带有一些命名限制。由于必须在父命名空间之后创建子模块名称,因此该名称不能是任何其他名称的子项或父项 goog.module(例如,goog.module('parent');并且 goog.module('parent.child');不能同时安全存在,也不能 goog.module('parent');goog.module('parent.child.grandchild');)。

3.3.4 ES6模块

不要使用ES6模块(即exportimport关键字),因为它们的语义尚未最终确定。请注意,一旦语义完全标准化,将重新审视此策略。

3.4 goog.require陈述

使用goog.require语句完成导入,在模块声明后立即组合在一起。每个都goog.require被分配给一个常量别名,或者被解构为几个常量别名。这些别名是引用required依赖关系的唯一可接受的方式,无论是在代码中还是在类型注释中:除非作为参数,否则永远不会使用完全限定名goog.require。别名应尽可能与导入模块名称的最终点分隔组件匹配,但可能包含其他组件(如果需要消除歧义,或者如果显着改进,则使用适当的套管使别名'套管仍能正确识别其类型)可读性。goog.require 语句可能不会出现在文件中的任何其他位置。

如果仅为其副作用导入模块,则可以省略分配,但完全限定的名称可能不会出现在文件中的任何其他位置。需要注释来解释为什么需要这样做并抑制编译器警告。

这些行按照以下规则排序:所有要求在左侧的名称首先出现,按字母顺序按这些名称排序。然后解构需要,再次按左侧的名称排序。最后,任何goog.require独立的调用(通常这些是针对其副作用导入的模块)。

提示:无需记住此订单并手动强制执行。您可以依靠IDE来报告未正确排序的需求。

如果长别名或模块名称会导致行超过80列限制,则不得包装:goog.require行是80列限制的例外。

例:

const MyClass = goog.require('some.package.MyClass');
const NsMyClass = goog.require('other.ns.MyClass');
const googAsserts = goog.require('goog.asserts');
const testingAsserts = goog.require('goog.testing.asserts');
const than80columns = goog.require('pretend.this.is.longer.than80columns');
const {clear,forEach,map} = goog.require('goog.array');
/ ** @suppress {extraRequire}初始化MyFramework。* /
goog.require( 'my.framework.initialization');

非法:

const randomName = goog.require('something.else'); //名称必须匹配const {clear,forEach,map} = //不要破坏行goog.require( 'goog.array');function someFunction(){const alias = goog.require('my.long.name.alias'); //必须在顶级// ...
}

3.4.1 goog.forwardDeclare

goog.forwardDeclare不经常需要,但它是打破循环依赖或引用后期加载代码的有用工具。这些陈述组合在一起,并紧跟任何goog.require陈述。一个 goog.forwardDeclare语句必须遵循相同的样式规则的 goog.require声明。

3.5文件的实现

在声明所有依赖性信息之后(由至少一个空行分隔)之后的实际实现。

这可能包括任何模块本地声明(常量,变量,类,函数等),以及任何导出的符号。

4格式化

术语注意类似块的构造是指类,函数,方法或大括号分隔的代码块的主体。请注意,通过 5.2数组文字和5.3对象文字,可以选择将任何数组或对象文字视为类似于块的结构。

提示:使用clang-format。JavaScript社区已投入精力确保clang格式在JavaScript文件上做正确的事情clang-format与几位受欢迎的编辑集成。

4.1大括号

4.1.1支架用于所有控制结构

大括号都需要所有的控制结构(即ifelsefordo, while,以及任何其他),即使身体只包含一个声明。非空块的第一个语句必须从它自己的行开始。

非法:

if(someVeryLongCondition())做一点事();for(let i = 0; i <foo.length; i ++)bar(foo [i]);

例外:一个简单的if语句可以完全放在一行而没有包装(并且没有else)可以保留在一行中,当它提高可读性时没有括号。这是控制结构可以省略大括号和换行符的唯一情况。

if(shortCondition())返回;

4.1.2非空块:K&R风格

大括号遵循Kernighan和Ritchie风格(埃及括号),用于 非空块和块状结构:

  • 开口支架前没有断线。
  • 开口支撑后换行。
  • 关闭括号前的换行符。
  • 如果该大括号终止语句或函数或类语句的主体或类方法,在大括号后的换行符。具体而言,有没有支架后换行符如果随后elsecatch, while,或逗号,分号,或右括号。

例:

class InnerClass {构造函数(){}/ ** @param {number} foo * /method(foo){if(condition(foo)){尝试{//注意:这可能会失败。东西();} catch(err){恢复();}}}
}

4.1.3空块:可能简洁

空块或块状结构可以在打开后立即关闭,其间没有字符,空格或换行符(即{}), 除非它是多块语句的一部分(直接包含多个块的语句)ifelsetrycatchfinally)。

例:

function doNothing(){}

非法:

if(condition){// ...
} else if(otherCondition){} else {// ...
}尝试{// ...
} catch(e){}

4.2块缩进:+2个空格

每次打开新的块或块状构造时,缩进都会增加两个空格。当块结束时,缩进返回到先前的缩进级别。缩进级别适用于整个块中的代码和注释。(参见4.1.2非空块中的示例:K&R样式)。

4.2.1数组文字:可选择块状

任何数组文字都可以选择格式化,就好像它是一个“块状结构”。例如,以下都是有效的(不是详尽的列表):

const a = [0,1,2,
]。const b =[0,1,2];
const c = [0,1,2];someMethod(foo,[0,1,2,
],酒吧);

允许其他组合,特别是在强调元素之间的语义分组时,但不应仅用于减少较大数组的垂直大小。

4.2.2对象文字:可选择块状

任何对象文字都可以选择格式化,就好像它是一个“块状结构”。相同的例子适用于4.2.1数组文字:可选的块状。例如,以下都是有效的(不是详尽的列表):

const a = {a:0,b:1,
};const b ={a:0,b:1};
const c = {a:0,b:1};someMethod(foo,{a:0,b:1,
},酒吧);

4.2.3类文字

类文字(无论是声明还是表达式)缩进为块。不要在方法之后添加分号,或者在类声明的右括号之后添加分号 (包含类表达式的赋值 - 如赋值 - 仍以分号结尾)。除非类扩展了模板化类型,否则请使用extends关键字,而不是 @extendsJSDoc注释。

例:

class Foo {constructor(){/ ** @type {number} * /this.x = 42;}/ ** @return {number} * /方法() {返回this.x;}
}
Foo.Empty = class {};
/ ** @extends {Foo <string>} * /
foo.Bar = class extends Foo {/ ** @override * /方法() {return super.method()/ 2;}
};/ ** @interface * /
class Frobnicator {/ ** @param {string}消息* /frobnicate(消息){}
}

4.2.4函数表达式

在函数调用的参数列表中声明匿名函数时,函数体将比前一个缩进深度缩进两个空格。

例:

prefix.something.reallyLongFunctionName('whatever',(a1,a2)=> {//相对于缩进深度缩进函数体+2//上面一行的'prefix'语句。if(a1.equals(a2)){someOtherLongFunctionName(A1);} else {andNowForSomethingCompletelyDifferent(a2.parrot);}
});some.reallyLongFunctionCall(arg1,arg2,arg3).thatsWrapped().then((result)=> {//相对于缩进深度缩进函数体+2//'.then()'调用。if(result){result.use();}});

4.2.5切换语句

与任何其他块一样,开关块的内容缩进为+2。

在切换标签之后,出现换行符,并且缩进级别增加+2,就像打开一个块一样。如果词法作用域需要,可以使用显式块。以下开关标签返回到先前的缩进级别,就像块已关闭一样。

break和以下情况之间的空行是可选的。

例:

开关(动物){case Animal.BANDERSNATCH:handleBandersnatch();打破;case Animal.JABBERWOCK:handleJabberwock();打破;默认:抛出新错误('未知动物');
}

4.3声明

4.3.1每行一个语句

每个语句后面都有一个换行符。

4.3.2分号是必需的

每个语句必须以分号结束。禁止依赖自动分号插入。

4.4柱限:80

JavaScript代码的列限制为80个字符。除非另有说明,否则任何超出此限制的行都必须换行,如 4.5换行中所述。

例外:

  1. 不能遵守列限制的行(例如,JSDoc中的长URL或要复制和粘贴的shell命令)。
  2. goog.modulegoog.require语句(参见3.3 goog.module语句和 3.4 goog.require语句)。

4.5换行

术语注意换行定义为将单个表达式分成多行。

有没有表现出全面的,确定性的公式究竟如何线路缠绕在每一种情况。通常有几种有效的方法来包装同一段代码。

注意:虽然换行的典型原因是为了避免溢出列限制,但即使是实际符合列限制的代码也可能由作者自行决定是否换行。

提示:提取方法或局部变量可以解决问题,而无需换行。

4.5.1在哪里打破

换行的主要指令是:更喜欢在更高的句法层面打破。

首选:

currentEstimate =calc(currentEstimate + x * currentEstimate)/2.0F;

灰心:

currentEstimate = calc(currentEstimate + x *currentEstimate)/ 2.0f;

在前面的例子中,从最高到最低的句法级别如下:赋值,除法,函数调用,参数,数字常量。

运算符包含如下:

  1. 当一条线在操作员处断开时,断点出现在符号之后。(请注意,这与Google风格的Java风格不同。)
    1. 这不适用于dot.),它实际上不是运算符。
  2. 方法或构造函数名称保持附加到其后面的左括号(()。
  3. 逗号(,)保持附加到其前面的标记。

注意:换行的主要目标是拥有清晰的代码,而不一定是适合最小行数的代码。

4.5.2缩进连续行至少+4个空格

当换行时,第一行(每个延续行)之后的每一从原始行缩进至少+4,除非它属于块缩进的规则。

当存在多个连续线时,压痕可以适当地变化超过+4。通常,更深层次的句法级别的连续行用4的较大倍数缩进,当且仅当它们以语法并行元素开头时,两行使用相同的缩进级别。

4.6.3水平对齐:不鼓励使用可变数量的空格来阻止某些令牌与前一行对齐。

4.6空白

4.6.1垂直空白

出现一个空白行:

  1. 在类或对象文字中的连续方法之间
    1. 例外:对象文字中两个连续属性定义之间的空行(它们之间没有其他代码)是可选的。根据需要使用这样的空行来创建字段的逻辑分组
  2. 在方法体内,谨慎地创建语句的逻辑分组。不允许在函数体的开头或结尾处出现空行。
  3. 可选地在类或对象文字中的第一个或最后一个方法之前(既不鼓励也不鼓励)。
  4. 按照本文档其他部分的要求(例如 3.4 goog.require语句)。

允许多个连续的空白行,但从不需要(也不鼓励)。

4.6.2水平空格

水平空白的使用取决于位置,并分为三大类:前导(在行的开头),尾随(在行的末尾)和内部。领先的空白(即缩进)在别处得到解决。禁止使用尾随空格。

除了语言或其他样式规则所要求的内容之外,除了文字,注释和JSDoc之外,单个内部ASCII空间也出现在以下位置。

  1. 分离任何保留字(如ifforcatch)从一个开括号((它后面在该行)。
  2. 将任何保留字(例如elsecatch)与}该行前面的右大括号()分开。
  3. 在任何打开大括号({)之前,有两个例外:
    1. 在作为函数的第一个参数或数组文字中的第一个元素的对象文字之前(例如foo({a: [{c: d}]}))。
    2. 在模板扩展中,因为它被语言禁止(例如abc${1 + 2}def)。
  4. 在任何二元或三元运算符的两边。
  5. 在逗号(,)或分号(;)之后。请注意,在这些字符之前绝不允许使用空格。
  6. :对象文字中冒号()之后。
  7. 在双斜杠(//)的两侧开始一行结束注释。这里允许多个空格,但不是必需的。
  8. 在打开JSDoc注释字符后和关闭字符的两边(例如,对于短格式类型声明或强制转换:this.foo = /** @type {number} */ (bar);function(/** string */ foo) {)。

4.6.3水平对齐:不鼓励

术语注意水平对齐是在代码中添加可变数量的附加空格的做法,目的是使某些标记直接出现在前一行的某些其他标记下方。

这种做法是允许的,但谷歌风格通常不鼓励这种做法。甚至不需要在已经使用过的地方保持水平对齐。

这是一个没有对齐的示例,后面跟一个对齐。两者都是允许的,但后者是不鼓励的:

{微小的:42,//这很棒更长:435,//这也是
};{微小:42,//允许,但未来的编辑更长:435,//可能会使它不对齐
};

提示:对齐可以提高可读性,但会为将来的维护带来问题。考虑一下需要触及一条线的未来变化。这种改变可能会使以前令人愉悦的格式化变得严重,并且这是允许的。更常见的是,它会提示编码人员(也许你)调整附近行的空白,这可能会引发一连串的重新格式化。那个单线变化现在有一个爆炸半径。这可能会导致无意义的忙碌工作,但最多它仍然会破坏版本历史信息,减慢审阅者的速度并加剧合并冲突。

4.6.4函数参数

希望将所有函数参数放在与函数名称相同的行上。如果这样做会超过80列限制,则参数必须以可读的方式换行。为了节省空间,您可以尽可能接近80,或者将每个参数放在自己的行上以增强可读性。缩进应该是四个空格。允许对齐括号,但不鼓励。以下是参数包装最常见的模式:

//参数从一个新行开始,缩进四个空格。首选的时候
//参数与函数名称(或关键字)不在同一行
//“功能”)但完全适合第二行。工作时间很长
//函数名称,无需重新定义即可重命名,空间不足。
做一点事(descriptiveArgumentOne,descriptiveArgumentTwo,descriptiveArgumentThree){// ...
}//如果参数列表较长,请换行80.使用较少的垂直空间,
//但违反了矩形规则,因此不推荐使用。
doSomething(veryDescriptiveArgumentNumberOne,veryDescriptiveArgumentTwo,tableModelEventHandlerProxy,artichokeDescriptorAdapterIterator){// ...
}//四个空格,每行一个参数。使用长函数名称,
//幸存重命名,并强调每个参数。
做一点事(veryDescriptiveArgumentNumberOne,veryDescriptiveArgumentTwo,tableModelEventHandlerProxy,artichokeDescriptorAdapterIterator){// ...
}

4.7分组括号:推荐

只有当作者和审阅者同意没有合理的机会在没有它们的情况下错误解释代码时,才会省略可选的分组括号,也不会使代码更易于阅读。它是不是 合理的假设,每个读者有记忆的整个运算符优先级表。

以下不要使用不必要的括号整个表达式 deletetypeofvoidreturnthrowcaseinof,或yield

类型转换需要括号:/** @type {!Foo} */ (foo)

4.8评论

本节介绍实现注释。JSDoc在7 JSDoc中单独解决。

4.8.1阻止评论风格

块注释与周围代码的缩进级别相同。他们可能是/* … */或者是//风格。对于多行/* … */注释,后续行必须以*与*前一行的对齐开头,以使注释显而易见,没有额外的上下文。只要值和方法名称没有充分表达含义,“参数名称”注释就应出现在值之后。

/ ** 这是* 好的。* /// 所以
// 这是。/ *这也很好。* /someFunction(obviousParam,true / * shouldRender * /,'hello'/ * name * /);

注释不包含在用星号或其他字符绘制的框中。

不要将JSDoc(/** … */)用于上述任何实现注释。

5语言功能

JavaScript包含许多可疑(甚至危险)的功能。本节描述了可能使用或未使用的功能,以及对其使用的任何其他限制。

5.1局部变量声明

5.1.1使用constlet

声明所有的局部变量有两种constlet。除非需要重新分配变量,否则默认使用const。将var 不得使用关键字。

5.1.2每个声明一个变量

每个局部变量声明只声明一个变量:声明,例如let a = 1, b = 2;未使用。

5.1.3在需要时声明,尽快初始化

局部变量不能习惯性地在其包含块或块状结构的开始申报。相反,局部变量被声明为接近它们首次使用的点(在合理范围内),以最小化它们的范围。

5.1.4根据需要声明类型

可以在声明上方的行上添加JSDoc类型注释,或者在变量名称之前添加内联。

例:

const / **!Array <number> * / data = [];/ ** @type {!Array <number>} * /
const data = [];

提示:在许多情况下,编译器可以推断模板化类型而不是其参数。当初始化文字或构造函数调用不包含模板参数类型的任何值(例如,空数组,对象,Maps或Sets),或者在闭包中修改变量时,尤其如此。在这些情况下,局部变量类型注释特别有用,否则编译器会将模板参数推断为未知。

5.2数组文字

5.2.1使用尾随逗号

每当最终元素和结束括号之间存在换行符时,请包含尾随逗号。

例:

const值= ['第一价值','第二价值',
]。

5.2.2不要使用可变参数Array构造函数

如果添加或删除参数,则构造函数容易出错。请改用文字。

非法:

const a1 = new Array(x1,x2,x3);
const a2 = new Array(x1,x2);
const a3 = new Array(x1);
const a4 = new Array();

除了第三种情况之外,这可以正常工作:if x1是一个整数然后 a3x1所有元素都是大小的数组undefined。如果x1是任何其他数字,那么将抛出异常,如果它是其他任何东西,那么它将是单元素数组。

相反,写

const a1 = [x1,x2,x3];
const a2 = [x1,x2];
const a3 = [x1];
const a4 = [];

new Array(length)适当时允许使用显式分配给定长度的数组。

5.2.3非数字属性

不要在数组上定义或使用非数字属性(除了 length)。使用Map(或Object)代替。

5.2.4解构

可以在赋值的左侧使用数组文字来执行解构(例如,从单个数组或可迭代解包多个值时)。可以包括最终的rest元素(...在变量名和变量名之间没有空格 )。如果未使用元素,则应省略元素。

const [a,b,c,... rest] = generateResults();
让[,b ,, d] = someArray;

解构也可以用于函数参数(请注意,参数名称是必需的但是被忽略)。[]如果结构化数组参数是可选的,则始终指定为默认值,并在左侧提供默认值:

/ ** @param {!Array <number> =} param1 * /
function optionalDestructuring([a = 4,b = 2] = []){...};

非法:

function badDestructuring([a,b] = [4,2]){...};

提示:对于(un)将多个值打包到函数的参数或返回中,尽可能将对象解构更改为数组解构,因为它允许命名单个元素并为每个元素指定不同的类型。*

5.2.5传播运营商

数组文字可以包括扩展运算符(...)以展平一个或多个其他迭代中的元素。应该使用扩展运算符而不是更笨拙的构造Array.prototype。之后没有空间 ...

例:

[... foo] //首选Array.prototype.slice.call(foo)
[... foo,... bar] //首选foo.concat(bar)

5.3对象文字

5.3.1使用尾随逗号

每当最终属性和右大括号之间存在换行符时,请包含尾随逗号。

5.3.2不要使用Object构造函数

虽然Object没有同样的问题Array,但仍然不允许一致性。请改用对象文字({}{a: 0, b: 1, c: 2})。

5.3.3不要混合引用和不引用的密钥

对象文字可以表示结构(带有不带引号的键和/或符号)或dicts(带引号和/或计算键)。不要在单个对象文字中混合使用这些键类型。

非法:

{a:42,// struct-style unquoted key'b':43,// dict-style引用键
}

5.3.4计算属性名称

{['key' + foo()]: 42}允许使用计算属性名称(例如),并且将其视为dict样式(引用)键(即,不得与非引用键混合),除非计算属性是符号(例如,[Symbol.iterator])。枚举值也可用于计算键,但不应与同一文字中的非枚举键混合使用。

5.3.5方法速记

可以使用方法shorthand({method() {… }})代替冒号后面紧跟一个function或箭头函数文字,在对象文字上定义方法。

例:

返回{东西:'糖果',方法() {归还这个。//返回'candy'},
};

请注意,this在方法简写中或function引用对象文字本身,而this在箭头函数中引用对象文字之外的范围。

例:

class {getObjectLiteral(){this.stuff ='fruit';返回{东西:'糖果',方法:()=> this.stuff,//返回'fruit'};}
}

5.3.6速记属性

对象文字允许使用速记属性。

例:

const foo = 1;
const bar = 2;
const obj = {FOO,酒吧,method(){return this.foo + this.bar; },
};
assertEquals(3,obj.method());

5.3.7解构

可以在赋值的左侧使用对象解构模式来执行解构并从单个对象解包多个值。

结构化对象也可以用作函数参数,但应尽可能简单:单个级别的不带引号的速记属性。嵌套和计算属性的更深层次可能不会用于参数解构。在destructured参数的左侧指定任何默认值({str = 'some default'} = {}而不是{str} = {str: 'some default'}),如果解构对象本身是可选的,则必须默认为{}。可以为destructured参数提供JSDoc任何名称(名称未使用但编译器需要)。

例:

/ *** @param {string}普通* @param {{num:(number | undefined),str:(string | undefined)} =} param1* num:做某事的次数。* str:用来做东西的字符串。* /
函数destructured(普通,{num,str ='some default'} = {})

非法:

/ ** @param {{x:{num:(number | undefined),str:(string | undefined)}}} param1 * /
function nestedTooDeeply({x:{num,str}}){};
/ ** @param {{num:(number | undefined),str:(string | undefined)} =} param1 * /
function nonShorthandProperty({num:a,str:b} = {}){};
/ ** @param {{a:number,b:number}} param1 * /
function computedKey({a,b,[a + b]:c}){};
/ ** @param {{a:number,b:string} =} param1 * /
function nontrivialDefault({a,b} = {a:2,b:4}){};

解构也可以用于goog.require语句,在这种情况下不能包装:整个语句占用一行,无论它有多长(参见3.4 goog.require语句)。

5.3.8枚举

通过将@enum注释添加到对象文字来定义枚举。定义后,可能无法将其他属性添加到枚举中。枚举必须是常量,所有枚举值必须是不可变的。

/ ***支持的温标。* @enum {string}* /
const TemperatureScale = {CELSIUS:'摄氏',FAHRENHEIT:'华氏',
};/ ***枚举有两个选项。* @enum {number}* /
const Option = {/ **使用的选项应该是第一个。* /FIRST_OPTION:1,/ **两个选项中的第二个。* /SECOND_OPTION:2,
};

5.4课程

5.4.1构造函数

具体类的构造函数是可选的。子类构造函数必须super()在设置任何字段或以其他方式访问之前调用 this。接口不能定义构造函数。

5.4.2字段

在构造函数中设置所有具体对象的字段(即除方法之外的所有属性)。注释永远不会重新分配的字段@const (这些字段不必非常不可变)。必须使用私有字段进行注释, @private并且其名称必须以尾随下划线结尾。字段永远不会设置在具体类上prototype

例:

class Foo {constructor(){/ ** @private @const {!Bar} * /this.bar_ = computeBar();}
}

提示:在构造函数完成后,绝不应将属性添加到实例或从实例中删除属性,因为它会显着阻碍VM的优化能力。如有必要,稍后初始化的字段应undefined在构造函数中显式设置为以防止以后的形状更改。添加 @struct到对象将检查未添加/访问未声明的属性。默认情况下,类会添加此类。

5.4.3计算属性

当属性是符号时,计算属性只能在类中使用。不允许使用Dict样式属性(即,引用或计算的非符号键,如5.3.3中所定义,不混合引用和不带引号的键)。[Symbol.iterator]应该为逻辑上可迭代的任何类定义一个 方法。除此之外,Symbol应谨慎使用。

提示:请小心使用任何其他内置符号(例如Symbol.isConcatSpreadable),因为它们不是由编译器填充的,因此不适用于旧版浏览器。

5.4.4静态方法

在不干扰可读性的地方,更喜欢模块本地函数而不是私有静态方法。

静态方法只应在基类本身上调用。不应该在包含动态实例的变量上调用静态方法,动态实例可以是构造函数或子类构造函数(@nocollapse如果已完成,则必须定义 ),并且不能直接在未定义方法的子类上调用本身。

非法:

class Base {/ ** @nocollapse * / static foo(){}}
class Sub扩展Base {}
function callFoo(cls){cls.foo(); } //劝阻:不要动态调用静态方法
Sub.foo(); //非法:不要在没有自己定义它的子类上调用静态方法

5.4.5旧式类声明

虽然ES6类是首选,但有些情况下ES6类可能不可行。例如:

  1. 如果存在或将存在子类(包括创建子类的框架),则无法立即将其更改为使用ES6类语法。如果这样的类使用ES6语法,则需要修改所有不使用ES6类语法的下游子类。

  2. this在调用超类构造函数之前需要已知值的框架,因为具有ES6超类的构造函数this在调用super返回之前无权访问实例值。

在所有其他方面的风格指南仍然适用于这样的代码:letconst,默认参数,休息和箭头的功能都应该用在适当的时候。

goog.defineClass 允许类似于ES6类语法的类类定义:

设C = goog.defineClass(S,{/ *** @param {string}值* /构造函数(值){S.call(this,2);/ ** @const * /this.prop = value;},/ *** @param {string} param* @return {number}* /method(param){返回0;},
});

或者,虽然goog.defineClass应该首选所有新代码,但也允许使用更传统的语法。

/ *** @constructor @extends {S}* @param {string}值* /
函数C(值){S.call(this,2);/ ** @const * /this.prop = value;
}
goog.inherits(C,S);/ *** @param {string} param* @return {number}* /
C.prototype.method = function(param){返回0;
};

如果存在超类,则应在调用超类构造函数之后在构造函数中定义每实例属性。应该在构造函数的原型上定义方法。

正确定义构造函数原型层次结构比首次出现更难!因此,最好是使用goog.inherits来自Closure库。

5.4.6不要prototype直接操纵s

class与定义prototype属性相比,该关键字允许更清晰,更易读的类定义。普通的实现代码没有业务操作这些对象,尽管它们仍然有用于定义5.4.5旧式类声明中定义的@record 接口和类。Mixins和修改内置对象的原型是明确禁止的。

例外:框架代码(如Polymer或Angular)可能需要使用prototypes,并且不应采用更差的解决方法来避免这样做。

例外:在接口中定义字段(参见5.4.9接口)。

5.4.7吸气剂和固定剂

不要使用JavaScript getter和setter属性。它们可能令人惊讶且难以推理,并且在编译器中的支持有限。改为提供普通方法。

例外:使用数据绑定框架(例如Angular和Polymer)时,可能会谨慎使用getter和setter。但请注意,编译器支持是有限的。使用它们时,必须使用get foo()set foo(value)在类或对象文字中定义它们,或者如果不可能,则使用Object.defineProperties。不要使用 Object.defineProperty,这会干扰属性重命名。吸气剂 不得改变可观察状态。

非法:

class Foo {get next(){return this.nextId ++; }
}

5.4.8覆盖toString

toString方法可能被覆盖,但必须始终成功,并且永远不会有可见的副作用。

提示:特别要注意从toString调用其他方法,因为异常条件可能导致无限循环。

5.4.9接口

接口可以用@interface或声明@record。声明的接口@record可以@implements由类或对象文字显式(即通过)或隐式实现。

接口上的所有非静态方法体必须是空块。必须在接口体之后定义字段作为存根prototype

例:

/ ***可以使用的东西。* @record* /
class Frobnicator {/ ***根据给定的策略执行frobnication。* @param {!FrobnicationStrategy}策略* /frobnicate(策略){}
}/ ** @type {number}放弃之前的尝试次数。* /
Frobnicator.prototype.attempts;

5.5功能

5.5.1顶级功能

导出的函数可以直接在exports对象上定义,也可以在本地声明并单独导出。鼓励使用非导出功能,不应声明@private

例子:

/ ** @return {number} * /
function helperFunction(){返回42;
}
/ ** @return {number} * /
function exportedFunction(){return helperFunction()* 2;
}
/ *** @param {string} arg* @return {number}* /
function anotherExportedFunction(arg){return helperFunction()/ arg.length;
}
/ ** @const * /
exports = {exportedFunction,anotherExportedFunction};
/ ** @param {string} arg * /
exports.foo =(arg)=> {//做一些事......
};

5.5.2嵌套函数和闭包

函数可能包含嵌套函数定义。如果为函数指定名称很有用,则应将其分配给本地const

5.5.3箭头功能

箭头函数提供了简洁的语法并修复了许多困难 this。首选箭头函数优先于function关键字,特别是嵌套函数(但请参见5.3.5方法简写)。

喜欢使用箭头功能f.bind(this),特别是结束 goog.bind(f, this)。避免写作const self = this。箭头函数对于回调特别有用,回调有时会传递意外的附加参数。

箭头的右侧可以是单个表达式或块。如果只有一个非破坏参数,则参数周围的括号是可选的。

提示:即使对于单参数箭头也使用括号是一个好习惯,因为如果在添加其他参数时忘记括号,代码仍然可以合理地解析(但不正确)。

5.5.4发电机

生成器启用了许多有用的抽象,可以根据需要使用。

定义生成器函数时,在存在时*function关键字附加到关键字,并使用函数名称中的空格将其分隔。当使用委托收益,附加*yield关键字。

例:

/ ** @return {!Iterator <number>} * /
function * gen1(){产量42;
}/ ** @return {!Iterator <number>} * /
const gen2 = function *(){yield * gen1();
}class SomeClass {/ ** @return {!Iterator <number>} * /* gen(){产量42;}
}

5.5.5参数

必须在函数定义之前的JSDoc中使用JSDoc注释键入函数参数,但在相同签名@overrides 的情况下除外,其中省略所有类型。

参数类型可以在参数名称之前的内联中指定(如(/** number */ foo, /** string */ bar) => foo + bar)。内联和 @param类型注释不能在同一个函数定义中混合使用。

5.5.5.1默认参数

使用参数列表中的equals运算符允许使用可选参数。可选参数必须包含equals运算符两侧的空格,其名称与所需参数完全相同(即不带前缀 opt_),=在JSDoc类型中使用后缀,在必需参数之后使用,而不使用产生可观察副作用的初始值设定项。所有可选参数必须在函数声明中具有默认值,即使该值为undefined

例:

/ *** @param {string}必需此参数始终是必需的。* @param {string =} optional此参数可以省略。* @param {!Node =} node另一个可选参数。* /
函数maybeDoSomething(必需,可选='',node = undefined){}

谨慎使用默认参数。当有少数几个可选参数没有自然顺序时,首选解构(如在5.3.7解构中 )以创建可读API。

注意:与Python的默认参数不同,可以使用返回新的可变对象(例如{}[])的初始化器,因为每次使用默认值时都会对初始化程序进行求值,因此不会在调用之间共享单个对象。

提示:虽然包含函数调用的任意表达式可以用作初始化程序,但这些表达式应尽可能简单。避免暴露共享可变状态的初始化器,因为这很容易在函数调用之间引入意外耦合。

5.5.5.2休息参数

使用rest参数而不是访问arguments。Rest参数...在其JSDoc中使用前缀键入。rest参数必须是列表中的最后一个参数。...参数名称和参数名称之间没有空格。不要命名rest参数var_args。永远不要命名局部变量或参数arguments,这会混淆内置名称。

例:

/ *** @param {!Array <string>}数组这是一个普通的参数。* @param {... number}数字参数的其余部分都是数字。* /
function variadic(array,... numbers){}

5.5.6退货

函数返回类型必须在函数定义正上方的JSDoc中指定,除非在相同签名@override的情况下,所有类型都被省略。

5.5.7泛型

必要时@template TYPE在类定义上方的JSDoc中声明泛型函数和方法。

5.5.8传播运营商

函数调用可以使用spread运算符(...)。Function.prototype.apply当数组或iterable被解包为可变函数的多个参数时,首选扩展运算符。之后没有空间...

例:

function myFunction(... elements){}
myFunction(... array,... iterable,... generator());

5.6字符串文字

5.6.1使用单引号

普通字符串文字用单引号(')分隔,而不是双引号(")。

提示:如果字符串包含单引号字符,请考虑使用模板字符串以避免必须转义引号。

普通的字符串文字可能不会跨越多行。

5.6.2模板字符串

`在复杂的字符串连接上使用模板字符串(分隔),尤其是涉及多个字符串文字时。模板字符串可能跨越多行。

如果模板字符串跨越多行,则不需要遵循封闭块的缩进,但是如果添加的空格无关紧要。

例:

函数算术(a,b){return`这是一个算术运算表:
$ {a} + $ {b} = $ {a + b}
$ {a}  -  $ {b} = $ {a  -  b}
$ {a} * $ {b} = $ {a * b}
$ {a} / $ {b} = $ {a / b}`;
}

5.6.3没有续行

不要在普通或模板字符串文字中使用行连续(即,在带有反斜杠的字符串文字中结束一行)。即使ES5允许这样做,如果任何尾随空格出现在斜杠之后,它也会导致棘手的错误,并且对读者来说不那么明显。

非法:

const longString ='这是一个非常长的字符串,远远超过了80列限制。不幸的是,它包含了很长的空间如何连续的线条缩进。';

相反,写

const longString ='这是一个非常长的字符串,远远超过80'+'列限制。它自'+'以来不包含很长的空间'串联的字符串更干净。';

5.7数字文字

数字可以用十进制,十六进制,八进制或二进制指定。使用完全相同0x, 0o0b前缀,以小写字母,十六进制,八进制,二进制和分别。除非紧接着,或x,否则不要包括前导零 。ob

5.8控制结构

5.8.1 For循环

使用ES6,语言现在有三种不同的for循环。但是可以使用全部forof尽可能优先使用循环。

forin循环只能用于dict风格的对象(参见 5.3.3不要混合带引号和不带引号的键),不应该用于迭代数组。 Object.prototype.hasOwnProperty应该在forin循环中使用以排除不需要的原型属性。身高forofObject.keys过 forin如果可能的话。

5.8.2例外情况

例外是该语言的一个重要部分,应在特殊情况发生时使用。总是抛出Errors或子类Error:永远不要抛出字符串文字或其他对象。new在构建时 总是使用Error

自定义异常提供了一种从函数中传递其他错误信息的好方法。应该在本机Error 类型不足的任何地方定义和使用它们。

更喜欢在临时错误处理方法上抛出异常(例如传递错误容器引用类型,或返回具有错误属性的对象)。

5.8.2.1空捕获块

在应对捕获的异常时不执行任何操作是非常正确的。如果真的适合在捕获区中不采取任何行动,那么合理的原因将在评论中解释。

尝试{return handleNumericResponse(response);
} catch(ok){//它不是数字; 那很好,继续
}
return handleTextResponse(response);

非法:

   尝试{shouldFail();失败('预期错误');}捕获(预期){}

提示:与其他一些语言不同,上述模式根本不起作用,因为这会捕获所引发的错误fail。请assertThrows()改用。

5.8.3切换语句

术语注意:开关块的大括号内有一个或多个语句组。每个语句组由一个或多个开关标签(case FOO:或者default:)组成,后跟一个或多个语句。

5.8.3.1跌倒:评论

在switch块内,每个语句组会突然终止(与 breakreturnthrowñ除外),或标有注释,表明执行会,也可能持续到下一个语句组。任何传达跌倒概念的评论都足够(通常// fall through)。在switch块的最后一个语句组中不需要此特殊注释。

例:

开关(输入){情况1:案例2:prepareOneOrTwo();//摔倒案例3:handleOneTwoOrThree();打破;默认:handleLargeNumber(输入);
}
5.8.3.2 default案件存在

每个switch语句都包含一个default语句组,即使它不包含任何代码。

5.9这个

this在类构造函数和方法中使用,或在类构造函数和方法中定义的箭头函数中使用。任何其他用法this必须@this在立即封闭函数的JSDoc中声明。

永远不要this用来引用全局对象,事件的上下文,eval事件的目标或不必要的call()ed或apply()ed函数。

5.10不允许的功能

5.10.1 with

不要使用with关键字。它使您的代码更难理解,并且自ES5以来一直在严格模式下被禁止。

5.10.2动态代码评估

不要使用evalFunction(...string)构造函数(代码加载器除外)。这些功能具有潜在的危险性,并且在CSP环境中无法正常工作。

5.10.3自动分号插入

始终使用分号终止语句(函数和类声明除外,如上所述)。

5.10.4非标准功能

不要使用非标准功能。这包括已删除的旧功能(例如WeakMap.clear),尚未标准化的新功能(例如,当前的TC39工作草案,任何阶段的提案或提议但尚未完成的Web标准)或专有功能仅在某些浏览器中实现。仅使用当前ECMA-262或WHATWG标准中定义的功能。(请注意,针对特定API编写的项目,例如Chrome扩展或Node.js,显然可以使用这些API)。禁止使用非标准语言“扩展”(例如某些外部转发器提供的扩展)。

5.10.5原始类型的包装器对象

从不使用new对原始对象包装(BooleanNumberString, Symbol),也不将它们包括在类型注释。

非法:

const / ** Boolean * / x = new Boolean(false);
if(x)alert(typeof x); //提醒'对象' -  WAT?

包装器可以被称为用于强制的函数(优选使用+或连接空字符串)或创建符号。

例:

const / ** boolean * / x = Boolean(0);
if(!x)alert(typeof x); //警告'boolean',如预期的那样

5.10.6修改内置对象

永远不要通过向构造函数或原型添加方法来修改内置类型。避免依赖于执行此操作的库。请注意,JSCompiler的运行时库将尽可能提供符合标准的polyfill; 没有别的可以修改内置对象。

除非绝对必要,否则不要向全局对象添加符号(例如,第三方API要求)。

6命名

6.1所有标识符共有的规则

标识符仅使用ASCII字母和数字,并且在下面提到的少数情况下,强调并且非常少(当像Angular这样的框架需要时)美元符号。

在合理范围内尽可能给出描述性的名称。不要担心保存水平空间,因为让新代码能够立即理解您的代码更为重要。不要在项目之外使用对于读者不明确或不熟悉的缩写,也不要通过删除单词中的字母来缩写。

priceCountReader //没有缩写。
numErrors //“num”是一种普遍的惯例。
numDnsConnections //大多数人都知道“DNS”代表什么。

非法:

n //毫无意义
nErr // Ambiguous缩写。
nCompConns // Ambiguous缩写。
wgcConnections //只有您的小组知道这代表什么。
pcReader //很多东西都可以缩写为“pc”。
cstmrId //删除内部字母。
kSecondsPerDay //不要使用匈牙利表示法。

6.2按标识符类型的规则

6.2.1包名称

包名都是lowerCamelCase。例如, my.exampleCode.deepSpace但不是my.examplecode.deepspacemy.example_code.deep_space

6.2.2班级名称

写入类,接口,记录和typedef名称UpperCamelCase。未经传播的类只是本地语言:它们没有标记@private,因此没有使用尾随下划线命名。

类型名称通常是名词或名词短语。例如,Request, ImmutableList,或VisibilityMode。另外,界面名称有时可能是形容词或形容词短语(例如Readable)。

6.2.3方法名称

方法名称是用lowerCamelCase。私有方法的名称必须以尾随下划线结尾。

方法名称通常是动词或动词短语。例如,sendMessage或 stop_。永远不需要属性的getter和setter方法,但是如果使用它们,则应该命名getFoo(或者可选地isFoo或者hasFoo 为布尔值)或者setFoo(value)用于setter。

下划线也可能出现在JsUnit测试方法名称中,以分隔名称的逻辑组件。test<MethodUnderTest>_<state>例如,一种典型的模式testPop_emptyStack。命名测试方法没有一种正确的方法。

6.2.4枚举名称

枚举名称是写成的UpperCamelCase,类似于类,通常应该是单数名词。枚举中的单个项目以 CONSTANT_CASE

6.2.5常量名称

常量名称使用CONSTANT_CASE:全部大写字母,单词用下划线分隔。没有理由使用尾随下划线来命名常量,因为私有静态属性可以由(隐式私有)模块本地替换。

6.2.5.1“常数”的定义

每个常量都是@const静态属性或模块本地const 声明,但并非所有@const静态属性和模块本地const都是常量。在选择常量情况之前,请考虑该字段是否真的像一个深不可变的常量。例如,如果该实例的任何可观察状态都可以改变,那么它几乎肯定不是常量。仅仅打算永远不会改变对象通常是不够的。

例子:

//常数
const NUMBER = 5;
/ ** @const * / exports.NAMES = ImmutableList.of('Ed','Ann');
/ ** @enum * / exports.SomeEnum = {ENUM_CONSTANT:'value'};//不是常量
let letVariable ='non-const';
class MyClass {constructor(){/ ** @const * / this.nonStatic ='non-static'; }};
/ ** @type {string} * / MyClass.staticButMutable ='not @const,可以重新分配';
const / ** Set <String> * / mutableCollection = new Set();
const / ** ImmutableSet <SomeMutableType> * / mutableElements = ImmutableSet.of(mutable);
const Foo = goog.require('my.Foo'); //镜像导入的名称
const logger = log.getLogger('loggers.are.not.immutable');

常数的名称通常是名词或名词短语。

6.2.5.1本地别名

只要它们提高了对完全限定名称的可读性,就应该使用本地别名。遵循与goog.requires(3.4 goog.require语句)相同的规则,维护别名的最后一部分。别名也可以在函数内使用。别名必须是const

例子:

const staticHelper = importedNamespace.staticHelper;
const CONSTANT_NAME = ImportedClass.CONSTANT_NAME;
const {assert,assertInstanceof} = asserts;

6.2.6非常量字段名称

写入非常量字段名称(静态或其他)lowerCamelCase,私有字段的尾部下划线。

这些名称通常是名词或名词短语。例如,computedValues 或index_

6.2.7参数名称

参数名称是写入的lowerCamelCase。请注意,即使参数需要构造函数,这也适用。

不应在公共方法中使用单字符参数名称。

例外:当第三方框架需要时,参数名称可以以a开头$。此异常不适用于任何其他标识符(例如,局部变量或属性)。

6.2.8局部变量名称

lowerCamelCase如上所述,除了模块本地(顶级)常量外,写入局部变量名。函数作用域中的常量仍然以lowerCamelCase。请注意,即使变量包含构造函数,lowerCamelCase也适用。

6.2.9模板参数名称

模板参数名称应该是简洁的单字或单字母标识符,并且必须是全部大写字母,例如TYPETHIS

6.3 Camel案例:已定义

有时将英语短语转换为驼峰大小写的方法不止一种,例如当存在首字母缩略词或类似IPv6或 iOS的异常构造时。为了提高可预测性,Google Style指定了以下(几乎)确定性方案。

从名称的散文形式开始:

  1. 将短语转换为纯ASCII并删除任何撇号。例如, Müller的算法可能会成为Muellers算法
  2. 将此结果划分为单词,拆分空格和任何剩余的标点符号(通常为连字符)。
    1. 推荐:如果任何单词已经具有常规使用的传统驼峰外观,请将其拆分为其组成部分(例如, AdWords成为广告词)。请注意,像iOS这样的单词本身并不是真正的驼峰; 它违反任何惯例,因此该建议不适用。
  3. 现在小写所有内容(包括首字母缩略词),然后只大写第一个字符:
    1. ......每个字,以产生上骆驼的情况,或
    2. ...除了第一个之外的每个词,以产生更低的骆驼案例
  4. 最后,将所有单词连接成一个标识符。

请注意,原始单词的大小几乎完全被忽略。

例子:

散文形式正确不正确
XML HTTP请求的XmlHttpRequestXMLHTTPRequest的
新客户IDnewCustomerIdnewCustomerID
内秒表innerStopwatchinnerStopWatch
在iOS上支持IPv6?supportsIpv6OnIossupportsIPv6OnIOS
YouTube导入器YouTubeImporterYoutubeImporter *

*可接受,但不推荐。

注意:有些单词在英语中含糊不清:例如,非空非空都是正确的,因此方法名称checkNonempty和checkNonEmpty同样都是正确的。

7 JSDoc

JSDoc用于所有类,字段和方法。

7.1一般表格

JSDoc块的基本格式如下例所示:

/ ***这里写了多行JSDoc文本,*正常包裹。* @param {number} arg要做某事的数字。* /
function doSomething(arg){...}

或者在这个单行示例中:

/ ** @const @private {!Foo}一小段JSDoc。* /
this.foo_ = foo;

如果单行注释溢出到多行,则必须使用多行样式/***/它们自己的行。

许多工具从JSDoc注释中提取元数据以执行代码验证和优化。因此,这些评论必须是格式良好的。

7.2降价

JSDoc是用Markdown编写的,尽管它可能在必要时包含HTML。

请注意,自动提取JSDoc的工具(例如JsDossier)通常会忽略纯文本格式,因此如果您这样做:

/ ***根据三个因素计算重量:*发送的项目*收到的物品*最后一个时间戳* /

它会像这样出现:

根据三个因素计算权重:项目发送的项目是上次收到的时间戳

相反,写一个Markdown列表:

/ ***根据三个因素计算重量:*  - 发送的项目*  - 收到的物品*  - 上次时间戳* /

7.3 JSDoc标签

Google风格允许使用JSDoc标记的子集。有关完整列表,请参见 9.1 JSDoc标记参考。大多数标签必须占据自己的行,标签位于行的开头。

非法:

/ ***“param”标记必须占用自己的行,不能合并。* @param {number}离开@param {number}吧* /
功能添加(左,右){...}

不需要任何附加数据简单的标记(如@private, @const@final@export)可以被组合到同一行,具有可选的类型在适当的时候沿。

/ ***放置更复杂的注释(如“工具”和“模板”)*在他们自己的路线上。多个简单标签(如“导出”和“最终”)*可以合并为一行。* @export @final* @implements {Iterable <TYPE>}* @template TYPE* /
class MyClass {/ *** @param {!ObjType} obj一些对象。* @param {number =} num可选数字。* /构造函数(obj,num = 42){/ ** @private @const {!Array <!ObjType | number>} * /this.data_ = [obj,num];}
}

何时组合标签或以何种顺序,但是一致,没有硬性规则。

有关JavaScript中注释类型的一般信息,请参阅 为Closure Compiler注释JavaScript和Closure Type System中的类型。

7.4换行

换行块标记缩进四个空格。包装的描述文本可以与前面的行描述对齐,但不鼓励这种水平对齐。

/ ***说明用于长参数/返回描述的换行。* @param {string} foo这是一个描述太长而无法适应的参数* 一条线。* @return {number}这会返回描述时间过长的内容*适合一行。* /
exports.method = function(foo){返回5;
};

包装@fileoverview描述时不要缩进。

7.5顶级/文件级注释

文件可能具有顶级文件概述。版权声明,作者信息和默认可见性级别是可选的。当文件由多个类定义组成时,通常建议使用文件概述。顶级评论旨在将不熟悉代码的读者定位到此文件中。如果存在,它可以提供文件内容的描述以及任何依赖性或兼容性信息。包裹的线条不缩进。

例:

/ *** @fileoverview文件描述,用途和信息*关于它的依赖关系。* @package* /

7.6课堂评论

必须使用描述和任何模板参数,实现的接口,可见性或其他适当的标记来记录类,接口和记录。类描述应该为读者提供足够的信息,以了解如何以及何时使用该类,以及正确使用该类所需的任何其他注意事项。构造函数可能省略了文本描述。@constructor@extends注释不与class关键字一起使用, 除非该类用于声明@interface或扩展泛型类。

/ ***一个更酷的事件目标,可以做很酷的事情。* @implements {Iterable <string>}* /
class MyFancyTarget扩展EventTarget {/ *** @param {string} arg1使这更有趣的参数。* @param {!Array <number>} arg2要处理的数字列表。* /构造函数(arg1,arg2){// ...}
};/ ***记录也很有帮助。* @extends {Iterator <TYPE>}* @record* @template TYPE* /
class Listable {/ ** @return {TYPE}要返回的行中的下一个项目。* /下一个() {}
}

7.7枚举和typedef注释

必须记录枚举和typedef。公共枚举和typedef必须具有非空描述。可以使用前一行的JSDoc注释记录单个枚举项。

/ ***一种有用的类型联合,经常被重用。* @typedef {!Bandersnatch |!BandersnatchType}* /
让CoolUnionType;/ *** bandersnatches的类型。* @enum {string}* /
const BandersnatchType = {/ **这种真是太酷了。* /FRUMIOUS:'太酷了',/ **不那么笨拙的那种。* /MANXOME:'manxome',
};

Typedef对于定义短记录类型或联合,复杂函数或泛型类型的别名非常有用。对于包含许多字段的记录类型,应避免使用Typedef,因为它们不允许记录单个字段,也不允许使用模板或递归引用。对于大型唱片类型,请选择@record

7.8方法和功能注释

必须记录参数和返回类型。this必要时应记录该类型。如果方法,参数和返回描述(但不是类型)从方法的其余部分JSDoc或其签名中显而易见,则可以省略它们。方法描述应以用第三人称声明语音写的句子开头。如果方法覆盖超类方法,则它必须包含@override注释。如果任何类型被细化,则重写的方法必须包括all @param@return注释,但如果类型完全相同则应省略它们。

/ **这是一堂课。* /
someClass扩展SomeBaseClass {/ ***在MyClass的一个实例上运行并返回一些东西。* @param {!MyClass} obj由于某种原因需要详细说明的对象*跨越多行的解释。* @param {!OtherClass} apparentOtherClass* @return {boolean}是否发生了什么事。* /someMethod(obj,obviousOtherClass){...}/ ** @override * /overriddenMethod(param){...}
}/ ***演示顶级函数如何遵循相同的规则。这个*制作一个数组。* @param {TYPE} arg* @return {!Array <TYPE>}* @template TYPE* /
function makeArray(arg){...}

匿名函数不需要JSDoc,但如果自动类型推断不足,则可以内联指定参数类型。

promise.then((/ **!Array <number | string> * / items)=> {doSomethingWith(项目);return / ** @type {string} * /(items [0]);});

7.9财产评论

必须记录属性类型。如果名称和类型提供了足够的文档来理解代码,则可以省略私有属性的描述。

公共导出的常量与属性的注释方式相同。对于@const从具有明显已知类型的表达式初始化的属性,可以省略显式类型。

提示:如果@const属性的类型直接来自具有声明类型的构造函数参数,或者直接来自具有声明的返回类型的函数调用,则可以将其视为“明显已知”。从更复杂的表达式分配的非const属性和属性应该明确声明它们的类型。

/** 我的课。* /
class MyClass {/ ** @param {string =} someString * /构造函数(someString ='default string'){/ ** @private @const * /this.someString_ = someString;/ ** @private @const {!OtherType} * /this.someOtherThing_ = functionThatReturnsAThing();/ ***每个窗格的最大数量。* @type {number}* /this.someProperty = 4;}
}/ ***放弃之前我们会尝试的次数。* @const* /
MyClass.RETRY_COUNT = 33;

7.10输入注释

类型的注释中发现@param@return@this,和@type标签,以及可选的@const@export和任何知名度的标签。附加到JSDoc标记的类型注释必须始终用大括号括起来。

7.10.1可空性

类型系统分别定义修饰符!?非null和可空。原始类型(undefinedstringnumberboolean, symbol,和function(...): ...),并记录文字({foo: string, bar: number})默认情况下非空。不要!为这些类型添加显式。对象类型(ArrayElementMyClass,等等)是通过缺省为空的,但不能从作为名称被立即分辨@typedef“d到一个非空逐默认类型。因此,除了基元和记录文字之外的所有类型都必须使用?或明确注释或!指示它们是否可为空。

7.10.2类型转换

在类型检查不能准确推断表达式类型的情况下,可以通过添加类型注释注释并将表达式括在括号中来收紧类型。请注意,括号是必需的。

/ ** @type {number} * /(x)

7.10.3模板参数类型

始终指定模板参数。这样编译器可以做得更好,它使读者更容易理解代码的作用。

坏:

const / **!Object * / users = {};
const / **!Array * / books = [];
const / **!Promise * / response = ...;

好:

const / **!Object <string,!User> * / users = {};
const / **!Array <string> * / books = [];
const / **!承诺<!Response> * / response = ...;const / **!Promise <undefined> * / thisPromiseReturnsNothingButParameterIsStillUseful = ...;
const / **!Object <string,*> * / mapOfEverything = {};

不应使用模板参数的情况:

  • Object 用于类型层次结构而不是类似地图的结构。

7.11可见性注释

可见性注释(@private,, )可以在块中指定@package@protected也可以@fileoverview在任何导出的符号或属性上指定。不要指定局部变量的可见性,无论是在函数内还是在模块的顶层。所有@private名称必须以下划线结尾。

8政策

8.1 Google风格未指定的问题:保持一致!

对于任何未通过此规范明确解决的样式问题,更喜欢执行同一文件中的其他代码已经在执行的操作。如果这不能解决问题,请考虑模拟同一包中的其他文件。

8.2编译器警告

8.2.1使用标准警告集

尽可能使用项目--warning_level=VERBOSE

8.2.2如何处理警告

在做任何事情之前,请确保您完全理解警告告诉您的内容。如果您不肯定为什么会出现警告,请寻求帮助。

理解警告后,请按顺序尝试以下解决方案:

  1. 首先,修复它或解决它。强烈尝试实际处理警告,或找到另一种方法来完成完全避免这种情况的任务。
  2. 否则,确定它是否是误报警。如果您确信警告无效且代码实际上是安全和正确的,请添加注释以使读者相信这一事实并应用@suppress 注释。
  3. 否则,请留下TODO评论。这是最后的选择。如果这样做,请不要取消警告。警告应该是可见的,直到可以正确处理。

8.2.3在最合理的范围内抑制警告

警告在最合理的范围内被抑制,通常是单个局部变量或非常小的方法。通常,仅为此原因提取变量或方法。

/ ** @suppress {uselessCode}无法识别'use asm'声明* /
function fn(){'使用asm';返回0;
}

即使是一个类中的大量抑制仍然比将整个类隐藏到这种类型的警告更好。

8.3弃用

标记已弃用的方法,类或带@deprecated注释的接口。弃用评论必须包含简单明了的方向,以便人们修复其呼叫站点。

8.4不适用于Google风格的代码

您偶尔会遇到代码库中不符合Google风格的文件。这些可能来自收购,或者可能是在Google Style在某个问题上占据一席之前编写的,或者可能由于任何其他原因而处于非Google风格。

8.4.1重新格式化现有代码

更新现有代码的样式时,请遵循以下准则。

  1. 不需要更改所有现有代码以符合当前样式指南。重新格式化现有代码是代码流失和一致性之间的权衡。样式规则随着时间的推移而发展,这些调整以保持合规性会产生不必要的流失。但是,如果对文件进行了重大更改,则预计该文件将采用Google风格。
  2. 注意不要让机会主义风格修复混淆CL的焦点。如果您发现自己进行了很多样式更改,这些更改对于CL的核心焦点并不重要,请将这些更改提升为单独的CL。

8.4.2新增代码:使用Google Style

全新文件使用Google Style,无论同一包中其他文件的样式选择如何。

将新代码添加到非Google风格的文件时,建议首先重新格式化现有代码,但需遵循8.4.1重新格式化现有代码中的建议 。

如果未执行此重新格式化,则新代码应尽可能与同一文件中的现有代码保持一致,但不得违反样式指南。

8.5本地风格规则

团队和项目可能会采用除本文档之外的其他样式规则,但必须接受清理更改可能不遵守这些附加规则,并且不得因违反任​​何其他规则而阻止此类清理更改。谨防过多的规则,没有任何目的。样式指南并不寻求在每种可能的场景中定义样式,也不应该。

8.6生成的代码:大多数是免除的

构建过程生成的源代码不需要采用Google Style。但是,任何从手写源代码引用的生成标识符都必须遵循命名要求。作为特殊例外,允许此类标识符包含下划线,这可能有助于避免与手写标识符冲突。

9附录

9.1 JSDoc标记引用

JSDoc在JavaScript中有多种用途。除了用于生成文档之外,它还用于控制工具。最着名的是Closure Compiler类型注释。

9.1.1键入注释和其他Closure Compiler注释

Closure编译器使用的JSDoc文档在闭包编译器的注释JavaScript和闭包类型系统中的类型中进行了描述 。

9.1.2文档注释

除了为Closure Compiler注释JavaScript中描述的JSDoc之外,以下标记是常见的,并且受到各种文档生成工具(例如JsDossier)的良好支持,仅用于文档目的。

标签模板和示例描述
@author 要么 @owner@author username@google.com (First Last)

例如:

/ *** @fileoverview用于处理textareas的实用程序。* @author kuth@google.com(Uthur Pendragon)* /
记录文件的作者或测试的所有者,通常仅在@fileoverview评论中使用。@owner单元测试仪表板使用该标记来确定谁拥有测试结果。

不建议。

@bug@bug bugnumber

例如:

/ ** @bug 1234567 * /
function testSomething(){// ...
}

/ ** * @bug 1234568 * @bug 1234569 * / function testTwoBugs(){ // ... }

指示给定测试函数回归测试的错误。

多个错误应该各自都有自己的@bug行,以便尽可能简单地搜索回归测试。

@code{@code ...}

例如:

/ ***移动到选择中的下一个位置。*当它出现{@code goog.iter.StopIteration}时*通过范围的结束。* @return {!Node}下一个位置的节点。* /
goog.dom.RangeIterator.prototype.next = function(){// ...
};
表示JSDoc描述中的术语是代码,因此可以在生成的文档中正确格式化。
@see@see Link

例如:

/ ***鲁莽地添加单个项目。* @see #addSafely* @see goog.Collect* @see goog.RecklessAdder #add* /
引用查找到另一个类函数或方法。
@supported@supported Description

例如:

/ *** @fileoverview事件管理器*提供抽象的接口*浏览器的事件系统。* @supported IE10 +,Chrome,Safari* /
在fileoverview中用于指示文件支持的浏览器。
@desc@desc Message description

例如:

/ ** @desc通知用户他们的帐户已创建。* /
exports.MSG_ACCOUNT_CREATED = goog.getMsg('您的帐户已经创建成功。');

 

您还可以在第三方代码中看到其他类型的JSDoc注释。这些注释出现在JSDoc Toolkit标记参考中,但不被视为有效Google风格的一部分。

9.1.3特定于框架的注释

以下注释特定于特定框架。

骨架标签文档
角度1@ngInject
聚合物@polymerBehaviorhttps://github.com/google/closure-compiler/wiki/Polymer-Pass

 

9.1.4关于标准Closure Compiler注释的注释

以下标记过去是标准的,但现在已弃用。

标签模板和示例描述
@expose@expose已过时。不使用。使用@export和/或@nocollapse 代替。
@inheritDoc@inheritDoc已过时。不使用。请@override改用。

 

9.2常被误解的风格规则

以下是关于Google Style for JavaScript的一些鲜为人知或常被误解的事实的集合。(以下是真实陈述;这不是神话列表

  • @author源文件中既不需要版权声明也不需要信用。(两者都没有明确推荐。)
  • 除了第一个构造函数(5.4.1构造函数)之外,没有强硬的规则来管理如何对类的成员进行排序(5.4类)。
  • 空块通常可以简洁地表示为{},如(4.1.3空块:可能简明)中所述。
  • 换行的主要指令是:更倾向于在更高的句法层面打破(4.5.1在哪里打破)。
  • 字符串文字,注释和Javadoc中允许使用非ASCII字符,实际上,当它们使代码比同等的Unicode转义符(2.3.3非ASCII字符)更容易阅读时,建议使用非ASCII字符。

存在以下工具以支持Google Style的各个方面。

9.3.1闭包编译器

该程序执行类型检查和其他检查,优化和其他转换(例如ECMAScript 6到ECMAScript 5代码降低)。

9.3.2 clang-format

该程序将JavaScript源代码重新格式化为Google Style,并且还遵循一些非必需但经常可读性增强的格式化实践。

clang-format不需要。允许作者改变其输出,允许审稿人要求进行此类更改; 争议以通常的方式解决。但是,子树可以选择在本地选择加入。

9.3.3 Closure编译器linter

该程序检查各种失误和反模式。

9.3.4一致性框架

JS一致性框架是一个工具,它是Closure Compiler的一部分,它为开发人员提供了一种简单的方法来指定一组额外的检查,以便在标准检查之上对其代码库运行。例如,一致性检查可以禁止访问某个属性,或者调用某个函数,或者丢失类型信息(未知数)。

这些规则通常用于强制执行关键限制(例如定义可能破坏代码库的全局变量)和安全模式(例如使用 eval或分配innerHTML),或者更松散地提高代码质量。

有关其他信息,请参阅JS一致性框架的官方文档 。

9.4传统平台的例外情况

9.4.1概述

本节描述了当代码作者无法使用现代ECMAScript 6语法时要遵循的异常和其他规则。如果无法使用ECMAScript 6语法,则需要使用推荐样式的例外情况,并在此处概述:

  • var允许使用声明
  • 使用arguments被允许
  • 允许使用没有默认值的可选参数

9.4.2使用 var

9.4.2.1 var声明不是块范围的

var声明的范围限定在最近的封闭函数,脚本或模块的开头,这可能会导致意外行为,尤其是var在循环内部引用声明的函数闭包时。以下代码给出了一个示例:

for(var i = 0; i <3; ++ i){var iteration = i;setTimeout(function(){console.log(iteration);},i * 1000);
}// log 2,2,2  -  NOT 0,1,2
//因为`iteration`是函数范围的,不是循环的本地。
9.4.2.2声明变量尽可能接近首次使用

尽管var声明的范围限定在封闭函数的开头,但var为了便于阅读,声明应尽可能接近它们的首次使用。但是,var如果在块外部引用该变量,则不要在块中放置声明。例如:

function sillyFunction(){var count = 0;for(var x in y){//“count”可以在这里声明,但不要这样做。计数++;}console.log(在y'中计算+'项目);
}
9.4.2.3使用@const作为常量变量

对于const将使用关键字的全局声明,如果可用,则var使用@const 注释声明(对于局部变量,这是可选的)。

9.4.3不要使用块作用域函数声明

难道不是这样做:

if(x){function foo(){}
}

虽然在ECMAScript 6支持功能声明之前实现的大多数JavaScript VM都没有标准化。实现彼此不一致,并且与块范围函数声明的现在标准ECMAScript 6行为不一致。ECMAScript 5和previous仅允许在脚本或函数的根语句列表中进行函数声明,并在严格模式下在块作用域中明确禁止它们。

要获得一致的行为,请使用var带有函数表达式的初始化来定义块中的函数:

if(x){var foo = function(){};
}

9.4.4使用goog.provide/进行依赖管理goog.require

goog.provide已弃用。goog.module即使在具有现有goog.provide用途的项目中,也应使用所有新文件。以下规则仅适用于预先存在的goog.provide文件。

9.4.4.1摘要
  • 将所有goog.provides放在第一位,goog.require第二位。单独提供需要空行。
  • 按字母顺序对条目排序(首先是大写)。
  • 不要包装goog.providegoog.require陈述。如有必要,可超过80列。
  • 仅提供顶级符号。

截至2016年10月,goog.providegoog.requiredependency管理已弃用。所有新文件,即使在使用goog.provide旧文件的项目中,也应该使用 goog.module

goog.provide语句应该组合在一起并放在第一位。所有 goog.require陈述都应遵循。这两个列表应该用空行分隔。

类似其他语言的导入语句,goog.provide并且 goog.require语句应该写在一行,即使超过80列线长度限制。

这些行应按字母顺序排序,首先是大写字母:

goog.provide( 'namespace.MyClass');
goog.provide( 'namespace.helperFoo');goog.require( 'an.extremelyLongNamespace.thatSomeoneThought.wouldBeNice.andNowItIsLonger.Than80Columns');
goog.require( 'goog.dom');
goog.require( 'goog.dom.TagName');
goog.require( 'goog.dom.classes');
goog.require( 'goog.dominoes');

在类上定义的所有成员应该在同一个文件中。只应在包含在同一个类上定义的多个成员的文件中提供顶级类(例如枚举,内部类等)。

做这个:

goog.provide( 'namespace.MyClass');

不是这个:

goog.provide( 'namespace.MyClass');
goog.provide( 'namespace.MyClass.CONSTANT');
goog.provide( 'namespace.MyClass.Enum');
goog.provide( 'namespace.MyClass.InnerClass');
goog.provide( 'namespace.MyClass.TypeDef');
goog.provide( 'namespace.MyClass.staticMethod');

也可以提供名称空间的成员:

goog.provide( 'foo.bar');
goog.provide( 'foo.bar.CONSTANT');
goog.provide( 'foo.bar.method');
9.4.4.2别名用 goog.scope

goog.scope已弃用。goog.scope即使在具有现有goog.scope使用的项目中,也不应使用新文件。

goog.scope可用于缩短使用goog.providegoog.requiredependency管理的代码中对命名空间符号的引用。

goog.scope每个文件只能添加一次调用。始终将其置于全局范围内。

开始goog.scope(function() {调用必须前面只有一个空行,并遵循任何goog.provide语句,goog.require语句或顶级注释。必须在文件的最后一行关闭调用。附加// goog.scope范围的结束语。将注释与分号分隔两个空格。

与C ++命名空间类似,不要在goog.scope声明下缩进。相反,从0列继续。

仅为不会重新分配给另一个对象的名称(例如,大多数构造函数,枚举和名称空间)创建别名。不要这样做(请参阅下面的如何为构造函数设置别名):

goog.scope(function(){
var Button = goog.ui.Button;Button = function(){...};
...

名称必须与它们是别名的全局的最后一个属性相同。

goog.provide( 'my.module.SomeType');goog.require( 'goog.dom');
goog.require( 'goog.ui.Button');goog.scope(function(){
var Button = goog.ui.Button;
var dom = goog.dom;//构造函数声明后别名新类型。
my.module.SomeType = function(){...};
var SomeType = my.module.SomeType;//像往常一样在原型上声明方法:
SomeType.prototype.findButton = function(){//上面有别名的按钮。this.button = new Button(dom.getElement('my-button'));
};
...
}); // goog.scope
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Dart-基础语法-更新

    Dart-基础语法 之前写过一篇基础语法&#xff0c; 后来读刘望舒的微信推文发现这篇总结的也挺全乎&#xff0c; 特别是环境搭建 &#xff0c;关键字&#xff0c;异常捕获&#xff0c; 类的继承部分 作为学习参考吧&#xff0c; 转载过来&#xff0c;也方便以后查阅。 原文链接…...

    2024/5/9 17:14:08
  2. vue前端开发规范

    本文主要从以下几个方面来概述前端的开发规范 目录构建规范前端命名规范前端工作规范开发文档的书写规范 前端目录构建规范 我们从命名原则、根目录、业务逻辑等方面进行目录构建 命名原则&#xff1a; 简洁明了&#xff08;如下&#xff1a;&#xff09; src 源代码img 图…...

    2024/5/9 19:28:58
  3. 双眼皮一个星期定型吗

    ...

    2024/5/9 21:17:48
  4. 王丽丹做双眼皮怎么样

    ...

    2024/5/9 18:02:53
  5. 爱美尔双眼皮手术失败案例

    ...

    2024/5/9 13:20:14
  6. 全切双眼皮能游泳

    ...

    2024/4/21 13:41:30
  7. 脸大的人适合哪种上海九院割双眼皮失败率

    ...

    2024/4/21 13:41:29
  8. Ionic创建项目失败:[ERROR] Network connectivity error occurred, are you offline?

    使用Iconi3 命令创建项目时会报错 创建命令: ionic start myapp2 tabs 错误详情: I:\AppSolution\Ionic_Solution>ionic start myapp2? What starter would you like to use: tabs √ Creating directory .\myapp2 - done!Downloading and extracting tabs starter -…...

    2024/4/21 13:41:28
  9. 大庆油田总院杨颖做双眼皮比较好地医院

    ...

    2024/4/21 13:41:26
  10. 金柱双眼皮切开与韩式三点哪个好

    ...

    2024/4/21 13:41:25
  11. 广尾开扇形双眼皮图片

    ...

    2024/4/21 13:41:25
  12. 前端三大框架脚手架如何配置运行的端口

    关于脚手架生成的运行端口配置 React 官方脚手架create-react-app&#xff1a; 修改生成后的package.json中的scripts "scripts": {"start": "set PORT8899 && react-scripts start","build": "react-scripts build&q…...

    2024/4/21 13:41:24
  13. 【Angular】Port 4200 is already in use. Use '--port' to specify a different port.修改端口号

    一、问题 在用angular的时候&#xff0c;出现了如下问题&#xff1a;二、原因 同时启动了多个angular项目。 因为4200的端口号已经被占用&#xff0c;换一个端口号就可以了。 三、方法 修改端口号 方法1.修改配置文件方法二、命令行修改端口号 ng serve --port 4201 上面我就把…...

    2024/4/21 13:41:22
  14. Linux Tomcat安装以及项目部署、端口修改详细教程

    1.下载安装tomcat&#xff08;http://tomcat.apache.org/&#xff09;自己选择与自己jdk匹配的版本&#xff0c;建议8.5 2.上传解压 mkdir /usr/local/tomcat&#xff08;新建文件夹&#xff0c;上传到该位置&#xff09; 解压 tar -zxvf apache-tomcat-8.5.42.tar.gz 3.启…...

    2024/4/21 13:41:22
  15. 双眼皮无痕手术怎么抽脂

    ...

    2024/4/20 15:51:28
  16. 上海双眼皮修复赞同伊莱美1

    ...

    2024/4/20 15:51:27
  17. Angular--A required parameter cannot follow an optional parameter.(必选参数不能位于可选参数后)

    前言 今天在为学习AngularJS4有关于管道的内容&#xff0c;因为第一次学习&#xff0c;所以不是很懂&#xff0c;遇到的问题肯定也是不少&#xff0c;今天就遇到了这样一个问题&#xff0c;如下&#xff1a; 内容 这个问题困惑了我将近两个小时&#xff0c;想在网上找寻相…...

    2024/4/20 15:51:26
  18. 一维声子晶体的谱有限元方法

    一维声子晶体的谱有限元方法 对于布洛赫周期边界条件的声子问题&#xff0c;通过物理建模&#xff0c;得到它的强形式是&#xff1a; 这里的杨氏模量和密度是分段函数&#xff1a; 对上述问题&#xff0c;做简单的代换&#xff0c;可以得到另一个周期化形式&#xff1a; …...

    2024/5/7 9:27:04
  19. npm 和 Yarn 的区别,Yarn 的使用方法

    1.Yarn是什么&#xff1f; Yarn 是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 &#xff0c;正如官方文档中写的&#xff0c;Yarn 是为了弥补 npm 的一些缺陷而出现的。 npm的缺点 npm install的时候巨慢。特别是新的项目拉下来要等半天&#…...

    2024/4/20 15:51:24
  20. 原生js替换jQuery各种方法-中文版

    原文https://github.com/nefe/You-D... 原生JS与jQuery操作DOM对比 You Dont Need jQuery 前端发展很快&#xff0c;现代浏览器原生 API 已经足够好用。我们并不需要为了操作 DOM、Event 等再学习一下 jQuery 的 API。同时由于 React、Angular、Vue 等框架的流行&#xff…...

    2024/4/20 15:51:23

最新文章

  1. 水平滑动与垂直滑动菜单

    水平滑动菜单 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}ul{background-color: #000;}ul li{text-shadow: none;display: inline-block;height: 40px;}ul li a{…...

    2024/5/10 0:19:44
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/9 21:23:04
  3. 3.java openCV4.x 入门-数据类型(CvType)与Scalar

    专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天 &#x1f9ed;文章导航&#x1f9ed; ⬆️ 2.hello openCV ⬇️ 4.待更新 数据类型&#xff…...

    2024/5/9 9:45:31
  4. C++类继承基础3——访问控制与继承

    私有继承 在C中&#xff0c;私有继承是一种继承方式&#xff0c;它定义了一个私有派生类&#xff0c;也称为派生类。私有继承意味着派生类继承了基类的所有成员&#xff0c;但这些成员在派生类中是私有的&#xff0c;对外部不可见。 要进行私有继承请使用private关键字&#…...

    2024/5/9 23:58:07
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/9 15:10:32
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/9 4:20:59
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/8 20:48:49
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/8 19:33:07
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/8 20:38:49
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/9 7:32:17
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/9 17:11:10
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57