首页 视频课程 主题开发课程第01章、开发准备 WordPress开发中JavaScript编码标准

WordPress开发中JavaScript编码标准

2022-12-12 / 387阅

JavaScript 已成为开发基于 WordPress 的应用程序(主题和插件)以及 WordPress 核心的关键组件。JavaScript 代码的格式和样式需要标准,以保持与 WordPress 标准为核心 PHP、HTML 和 CSS 代码提供的相同的代码一致性。

任何代码库中的所有代码都应该看起来像一个人输入的,不管有多少人贡献。–编写一致、惯用的 JavaScript 的原则

WordPress JavaScript 编码标准改编自jQuery JavaScript 风格指南。我们的标准在以下方面与 jQuery 指南不同:

  • WordPress 使用单引号来声明字符串。
  • Case 语句在 switch 块中缩进。
  • 函数内容一致缩进,包括完整文件闭包包装器。
  • 为了与 WordPress PHP 编码标准保持一致,一些空白规则有所不同。
  • 鼓励使用 jQuery 的 100 个字符的硬行限制,但并不严格执行。

下面的许多示例都直接改编自 jQuery 样式指南;这些差异都已集成到本页的示例中。以下任何标准和示例都应被视为 WordPress 代码的最佳实践,除非明确指出为反模式。

代码重构

“不应该仅仅因为我们可以就进行代码重构。” – 首席开发人员 Andrew Nacin

JavaScript 的 WordPress 代码结构的许多部分在风格上是不一致的。WordPress 正在努力逐步改进这一点,因此代码将干净利落,一目了然。

虽然编码标准很重要,但仅仅为了符合标准而重构旧的 .js 文件并不是一个紧迫的问题。强烈建议不要为旧文件打“纯空白”补丁。

所有新的或更新的 JavaScript 代码都将被审查以确保其符合标准并通过 JSHint。

间距

在整个代码中大量使用空格。“如有疑问,请将其隔开。”

这些规则鼓励自由间距以提高开发人员的可读性。缩小过程会创建一个文件,该文件针对浏览器进行了优化以供读取和处理。

  • 带制表符的缩进。
  • 行尾或空行上没有空格。
  • 行通常不应超过 80 个字符,并且不应超过 100 个(将制表符算作 4 个空格)。这是一个“软”规则,但长行通常表示代码不可读或混乱。
  • if// elsefor/块应该总是使用大括号,并且总是在多行上whiletry
  • 一元特殊字符运算符(例如 , ++--的操作数旁边不能有空格。
  • Any ,and;前面不能有空格。
  • 任何;用作语句终止符的都必须在行尾。
  • 对象定义中属性名称之后的任何:内容都不能有前面的空格。
  • 三元条件中的?and:两边必须有空格。
  • 空结构中没有填充空间(例如{},,,,[]fn()
  • 每个文件的末尾应该有一个新行。
  • 任何!否定运算符都应有以下空格。*
  • 所有函数体都缩进一个制表符,即使整个文件都包含在一个闭包中。*
  • 空格可以对齐文档块内或一行内的代码,但只能在行首使用制表符。*

* : WordPress JavaScript 标准比 jQuery 风格指南更喜欢更广泛的空白规则。这些偏差是为了 WordPress 代码库中 PHP 和 JavaScript 文件之间的一致性。

空格很容易堆积在一行的末尾——避免这种情况,因为尾随空格在 JSHint 中会被视为错误。捕捉空格堆积的一种方法是在文本编辑器中启用可见的空格字符。

对象声明

如果对象声明很短,则可以在一行中进行(记住行长度准则)。当对象声明太长无法放在一行时,每行必须有一个属性。如果属性名称是保留字或包含特殊字符,则只需要引用它们:

如果对象和数组很短,则可以在一行中声明它们(记住行长度准则)。当一个对象或数组太长而无法放在一行中时,每个成员都必须放在自己的行中,并且每行以逗号结尾。

// Preferred
var obj = {
    ready: 9,
    when: 4,
    'you are': 15,
};
var arr = [
    9,
    4,
    15,
];

// Acceptable for small objects and arrays
var obj = { ready: 9, when: 4, 'you are': 15 };
var arr = [ 9, 4, 15 ];

// Bad
var obj = { ready: 9,
    when: 4, 'you are': 15 };
var arr = [ 9,
    4, 15 ]; 

数组和函数调用

始终在元素和参数周围包含额外的空格:

array = [ a, b ];

foo( arg );

foo( 'string', object );

foo( options, object[ property ] );

foo( node, 'property', 2 );

prop = object[ 'default' ];

firstArrayElement = arr[ 0 ]; 

良好间距的例子

var i;

if ( condition ) {
    doSomething( 'with a string' );
} else if ( otherCondition ) {
    otherThing( {
        key: value,
        otherKey: otherValue
    } );
} else {
    somethingElse( true );
}

// Unlike jQuery, WordPress prefers a space after the ! negation operator.
// This is also done to conform to our PHP standards.
while ( ! condition ) {
    iterating++;
}

for ( i = 0; i < 100; i++ ) {
    object[ array[ i ] ] = someFn( i );
    $( '.container' ).val( array[ i ] );
}

try {
    // Expressions
} catch ( e ) {
    // Expressions
} 

缩进和换行

缩进和换行符增加了复杂语句的可读性。

制表符应该用于缩进。即使整个文件包含在一个闭包中(即一个立即调用的函数),该函数的内容也应该缩进一个制表符:

( function ( $ ) {
    // Expressions indented

    function doSomething() {
        // Expressions indented
    }
} )( jQuery ); 

块和大括号

ifelseforwhile, 和try块应该总是使用大括号,并且总是在多行上。左大括号应与函数定义、条件语句或循环位于同一行。右大括号应该紧跟在块的最后一条语句之后。

var a, b, c;

if ( myFunction() ) {
    // Expressions
} else if ( ( a && b ) || c ) {
    // Expressions
} else {
    // Expressions
} 

多行语句

当语句太长无法放在一行中时,换行符必须出现在运算符之后。

// Bad
var html = '<p>The sum of ' + a + ' and ' + b + ' plus ' + c
    + ' is ' + ( a + b + c ) + '</p>';

// Good
var html = '<p>The sum of ' + a + ' and ' + b + ' plus ' + c +
    ' is ' + ( a + b + c ) + '</p>'; 

如果可以提高可读性,就应该将行分成逻辑组,例如将三元运算符的每个表达式拆分到自己的行中,即使两者都适合一行。

// Acceptable
var baz = ( true === conditionalStatement() ) ? 'thing 1' : 'thing 2';

// Better
var baz = firstCondition( foo ) && secondCondition( bar ) ?
    qux( foo, bar ) :
    foo; 

当条件太长而无法放在一行中时,布尔表达式中逻辑运算符的每个操作数都必须出现在自己的行中,从左括号和右括号缩进一层。

if (
    firstCondition() &&
    secondCondition() &&
    thirdCondition()
) {
    doStuff();
} 

链式方法调用

当一连串的方法调用太长而不能放在一行中时,每行必须有一个调用,第一个调用与调用方法的对象分开一行。如果该方法更改了上下文,则必须使用额外的缩进级别。

elements
    .addClass( 'foo' )
    .children()
        .html( 'hello' )
    .end()
    .appendTo( 'body' ); 

const用and声明变量let

对于使用 ES2015 或更新版本编写的代码,constlet始终代替var. 声明应该使用const,除非它的值将被重新分配,在这种情况下let是合适的。

与 不同var,不必在函数顶部声明所有变量。相反,它们将在首次使用时声明。

声明变量var

每个函数都应以单个逗号分隔的语句开头,该var语句声明任何必要的局部变量。如果函数未使用 声明变量var,则该变量可能会泄漏到外部作用域(通常是全局作用域,这是最坏的情况),并且可能会无意中引用和修改该数据。

语句中的赋值var应该在单独的行中列出,而声明可以分组在一行中。任何额外的行都应该用额外的制表符缩进。占用多于几行的对象和函数应该在var语句之外分配,以避免过度缩进。

// Good
var k, m, length,
    // Indent subsequent lines by one tab
    value = 'WordPress';

// Bad
var foo = true;
var bar = false;
var a;
var b;
var c; 

全局变量

过去,WordPress 核心更多地使用全局变量。由于核心 JavaScript 文件有时会在插件中使用,因此不应删除现有的全局变量。

文件中使用的所有全局变量都应记录在该文件的顶部。多个全局变量可以用逗号分隔。

此示例将passwordStrength在该文件中创建一个允许的全局变量:

/* global passwordStrength:true */ 

后面的“真”passwordStrength意味着这个全局是在这个文件中定义的。如果您正在访问在别处定义的全局,请忽略:true将全局指定为只读。

公共图书馆

Backbone、jQuery、Underscore 和全局wp对象都在根.jshintrc文件中注册为允许的全局对象。

可以随时直接访问 Backbone 和 Underscore。应该通过$jQuery对象传递给匿名函数来访问 jQuery:复制

( function ( $ ) {
    // Expressions
} )( jQuery ); 

这将不需要调用.noConflict(),或$使用另一个变量进行设置。

添加或修改wp对象的文件必须安全地访问全局以避免覆盖以前设置的属性:

// At the top of the file, set "wp" to its existing value (if present)
window.wp = window.wp || {}; 

命名约定

变量和函数名称应该是完整的单词,使用首字母小写的驼峰式大小写。这是该标准与WordPress PHP 编码标准不同的地方。

名称应该是描述性的,但不要过分。迭代器允许有例外,例如使用i来表示循环中的索引。

缩写与首字母缩略词

首字母缩略词的每个组成字母必须大写。这是为了反映首字母缩略词的每个字母都是其扩展形式的正确单词。

所有其他缩写必须采用驼峰式大小写,首字母大写,后跟小写字母。

如果缩写词或首字母缩略词出现在变量名的开头,则必须遵循驼峰命名规则,包括变量或类定义的第一个字母。对于变量赋值,这意味着将缩写完全写成小写。对于类定义,其首字母应大写。

// "Id" is an abbreviation of "Identifier":
const userId = 1;

// "DOM" is an acronym of "Document Object Model":
const currentDOMDocument = window.document;

// Acronyms and abbreviations at the start of a variable name are consistent
// with camelcase rules covering the first letter of a variable or class.
const domDocument = window.document;
class DOMDocument {}
class IdCollection {} 

类定义

用于 withnew的构造函数首字母应大写 (UpperCamelCase)。

定义必须使用classUpperCamelCase约定,无论它是否打算与new构造一起使用。

class Earth {
    static addHuman( human ) {
        Earth.humans.push( human );
    }

    static getHumans() {
        return Earth.humans;
    }
}

Earth.humans = []; 

所有@wordpress/element组件,包括无状态功能组件,都应使用类定义命名规则进行命名,以保持一致性并反映组件可能需要从功能转换为类而不破坏兼容性的事实。

常量

驼峰式大小写的例外是常量值,它们永远不会被重新分配或改变。此类变量必须使用SCREAMING_SNAKE_CASE 约定。

在几乎所有情况下,常量都应定义在文件的最顶层范围内。重要的是要注意JavaScript 的const赋值在概念上比这里暗示的更受限制,JavaScript 中赋值的值const实际上可以被改变,并且只能防止重新赋值。这些编码指南中定义的常量仅适用于预期永远不会改变的值,并且是开发人员传达意图的策略,而不是技术限制。

注释

注释出现在它们引用的代码之前,并且应该始终以空行开头。将评论的第一个字母大写,并在写完整句子时在末尾加上句号。//评论标记 ( ) 和评论文本之间必须有一个空格。

someStatement();

// Explanation of something complex on the next line
$( 'p' ).doSomething();

// This is a comment that is long enough to warrant being stretched
// over the span of multiple lines. 

JSDoc 注释应该使用/**多行注释开头。有关详细信息,请参阅JavaScript 文档标准。

当用于注释形式参数列表中的特殊参数时,允许内联注释作为例外:

function foo( types, selector, data, fn, /* INTERNAL */ one ) {
    // Do stuff
} 

平等

===必须使用严格相等检查 ( ) 来支持抽象相等检查 ( ==)。

类型检查

这些是检查对象类型的首选方法:

  • 细绳:typeof object === 'string'
  • 数字:typeof object === 'number'
  • 布尔值:typeof object === 'boolean'
  • 对象:typeof object === 'object'_.isObject( object )
  • 普通对象:jQuery.isPlainObject( object )
  • 功能:_.isFunction( object )jQuery.isFunction( object )
  • 数组:_.isArray( object )jQuery.isArray( object )
  • 元素:object.nodeType_.isElement( object )
  • 无效的:object === null
  • 空或未定义:object == null
  • 不明确的:
    • 全局变量:typeof variable === 'undefined'
    • 局部变量:variable === undefined
    • 特性:object.prop === undefined
    • 以上任何一项:_.isUndefined( object )

在已经使用 Backbone 或 Underscore 的任何地方,我们鼓励您使用Underscore.js的类型检查方法而不是 jQuery 的。

字符串

对字符串文字使用单引号:

var myStr = 'strings should be contained in single quotes'; 

当字符串中包含单引号时,需要使用反斜杠 ( \) 进行转义:

// Escape single quotes within strings:
'Note the backslash before the \'single quotes\''; 

开关语句

通常不鼓励使用switch语句,但在存在大量案例时很有用——尤其是当多个案例可以由同一个块处理,或者default可以利用 fall-through 逻辑(案例)时。

使用switch语句时:

  • break对除 以外的每种情况使用 a default。当允许语句“失败”时,请明确注意。
  • case在 . 中将语句缩进一个选项卡switch
switch ( event.keyCode ) {
    // ENTER and SPACE both trigger x()
    case $.ui.keyCode.ENTER:
    case $.ui.keyCode.SPACE:
        x();
        break;
    case $.ui.keyCode.ESCAPE:
        y();
        break;
    default:
        z();
} 

不建议从 switch 语句中返回值:使用case块设置值,然后return在最后设置这些值。

function getKeyCode( keyCode ) {
    var result;

    switch ( event.keyCode ) {
        case $.ui.keyCode.ENTER:
        case $.ui.keyCode.SPACE:
            result = 'commit';
            break;
        case $.ui.keyCode.ESCAPE:
            result = 'exit';
            break;
        default:
            result = 'default';
    }

    return result;
} 

数组

在 JavaScript 中创建数组应该使用速记[]构造函数而不是new Array()符号来完成。

var myArray = []; 

您可以在构造期间初始化数组:

var myArray = [ 1, 'WordPress', 2, 'Blog' ]; 

在 JavaScript 中,关联数组被定义为对象。

对象

在 JavaScript 中创建对象的方法有很多种。对象字面量表示法{}是性能最高的,也是最容易阅读的。

var myObj = {}; 

除非对象需要特定的原型,否则应使用对象文字表示法,在这种情况下,应通过调用构造函数来创建对象new

var myObj = new ConstructorMethod(); 

对象属性应该通过点表示法访问,除非键是变量或不是有效标识符的字符串:

prop = object.propertyName;
prop = object[ variableKey ];
prop = object['key-with-hyphens']; 

迭代

当使用循环遍历大型集合for时,建议将循环的最大值存储为变量,而不是每次都重新计算最大值:

// Good & Efficient
var i, max;

// getItemCount() gets called once
for ( i = 0, max = getItemCount(); i < max; i++ ) {
    // Do stuff
}

// Bad & Potentially Inefficient:
// getItemCount() gets called every time
for ( i = 0; i < getItemCount(); i++ ) {
    // Do stuff
} 

阅读文章或者观看视频过程中有任何问题,请下方留言或者联系我Q248758228

大家谈论
    我的见解
    目录