no-unused-expressions
禁止未使用的表达式
对程序状态没有影响的未使用表达式表示逻辑错误。
¥An unused expression which has no effect on the state of the program indicates a logic error.
例如,n + 1;
不是语法错误,但它可能是一个打字错误,程序员的意思是赋值语句 n += 1;
。有时,这些未使用的表达式可能会被生产环境中的某些构建工具消除,这可能会破坏应用逻辑。
¥For example, n + 1;
is not a syntax error, but it might be a typing mistake where a programmer meant an assignment statement n += 1;
instead. Sometimes, such unused expressions may be eliminated by some build tools in production environment, which possibly breaks application logic.
规则详情
¥Rule Details
该规则旨在消除对程序状态没有影响的未使用表达式。
¥This rule aims to eliminate unused expressions which have no effect on the state of the program.
此规则不适用于带有 new
运算符的函数调用或构造函数调用,因为它们可能对程序的状态产生副作用。
¥This rule does not apply to function calls or constructor calls with the new
operator, because they could have side effects on the state of the program.
let i = 0;
function increment() { i += 1; }
increment(); // return value is unused, but i changed as a side effect
let nThings = 0;
function Thing() { nThings += 1; }
new Thing(); // constructed object is unused, but nThings changed as a side effect
此规则不适用于使用 ES5+ 环境的指令(指令的形式为字面量字符串表达式,例如位于脚本、模块或函数开头的 "use strict";
)。在 ES3 环境中,指令默认被视为未使用的表达式,但可以使用 ignoreDirectives
选项更改此行为。
¥This rule does not apply to directives (which are in the form of literal string expressions such as "use strict";
at the beginning of a script, module, or function) when using ES5+ environments. In ES3 environments, directives are treated as unused expressions by default, but this behavior can be changed using the ignoreDirectives
option.
序列表达式(使用逗号的那些,例如 a = 1, b = 2
)总是被认为是未使用的,除非它们的返回值被分配或用于条件评估,或者使用序列表达式值进行函数调用。
¥Sequence expressions (those using a comma, such as a = 1, b = 2
) are always considered unused unless their return value is assigned or used in a condition evaluation, or a function call is made with the sequence expression value.
选项
¥Options
此规则在其默认状态下不需要任何参数。如果你想启用以下一项或多项功能,你可以传递一个带有如下选项设置的对象:
¥This rule, in its default state, does not require any arguments. If you would like to enable one or more of the following you may pass an object with the options set as follows:
-
将
allowShortCircuit
设置为true
将允许你在表达式中使用短路计算(默认值:false
)。¥
allowShortCircuit
set totrue
will allow you to use short circuit evaluations in your expressions (Default:false
). -
将
allowTernary
设置为true
将使你能够在表达式中使用三元运算符,类似于短路计算(默认值:false
)。¥
allowTernary
set totrue
will enable you to use ternary operators in your expressions similarly to short circuit evaluations (Default:false
). -
将
allowTaggedTemplates
设置为true
将使你能够在表达式中使用标记模板字面量(默认值:false
)。¥
allowTaggedTemplates
set totrue
will enable you to use tagged template literals in your expressions (Default:false
). -
enforceForJSX
设置为true
将标记未使用的 JSX 元素表达式(默认值:false
)。¥
enforceForJSX
set totrue
will flag unused JSX element expressions (Default:false
). -
将
ignoreDirectives
设置为true
将阻止指令在使用ecmaVersion: 3
(默认值:false
)进行 linting 时被报告为未使用的表达式。¥
ignoreDirectives
set totrue
will prevent directives from being reported as unused expressions when linting withecmaVersion: 3
(Default:false
).
仅当所有代码路径直接更改状态(例如,赋值语句)或可能具有副作用(例如,函数调用)时,这些选项才允许未使用的表达式。
¥These options allow unused expressions only if all of the code paths either directly change the state (for example, assignment statement) or could have side effects (for example, function call).
默认 { "allowShortCircuit": false, "allowTernary": false }
选项的错误代码示例:
¥Examples of incorrect code for the default { "allowShortCircuit": false, "allowTernary": false }
options:
/*eslint no-unused-expressions: "error"*/
0
if(0) 0
{0}
f(0), {}
a && b()
a, b()
c = a, b;
a() && function namedFunctionInExpressionContext () {f();}
(function anIncompleteIIFE () {});
injectGlobal`body{ color: red; }`
默认 { "allowShortCircuit": false, "allowTernary": false }
选项的正确代码示例:
¥Examples of correct code for the default { "allowShortCircuit": false, "allowTernary": false }
options:
/*eslint no-unused-expressions: "error"*/
{} // In this context, this is a block statement, not an object literal
{ myLabel: foo() } // In this context, this is a block statement with a label and expression, not an object literal
function namedFunctionDeclaration () {}
(function aGenuineIIFE () {}());
f()
a = 0
new C
delete a.b
void a
请注意,一个或多个字符串表达式语句(带或不带分号)只有在它们不在脚本、模块或函数的开头(单独且不受其他语句中断)时才会被视为未使用。否则,它们将被视为 “指示序言” 的一部分,这是 JavaScript 引擎可能使用的部分。这包括 “严格模式” 指令。
¥Note that one or more string expression statements (with or without semi-colons) will only be considered as unused if they are not in the beginning of a script, module, or function (alone and uninterrupted by other statements). Otherwise, they will be treated as part of a “directive prologue”, a section potentially usable by JavaScript engines. This includes “strict mode” directives.
有关指令的此规则的正确代码示例:
¥Examples of correct code for this rule in regard to directives:
/*eslint no-unused-expressions: "error"*/
"use strict";
"use asm"
"use stricter";
"use babel"
"any other strings like this in the directive prologue";
"this is still the directive prologue";
function foo() {
"bar";
}
class Foo {
someMethod() {
"use strict";
}
}
有关指令的此规则的错误代码示例:
¥Examples of incorrect code for this rule in regard to directives:
/*eslint no-unused-expressions: "error"*/
doSomething();
"use strict"; // this isn't in a directive prologue, because there is a non-directive statement before it
function foo() {
"bar" + 1;
}
class Foo {
static {
"use strict"; // class static blocks do not have directive prologues
}
}
allowShortCircuit
{ "allowShortCircuit": true }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowShortCircuit": true }
option:
/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true }]*/
a || b
{ "allowShortCircuit": true }
选项的正确代码示例:
¥Examples of correct code for the { "allowShortCircuit": true }
option:
/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true }]*/
a && b()
a() || (b = c)
allowTernary
{ "allowTernary": true }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowTernary": true }
option:
/*eslint no-unused-expressions: ["error", { "allowTernary": true }]*/
a ? b : 0
a ? b : c()
{ "allowTernary": true }
选项的正确代码示例:
¥Examples of correct code for the { "allowTernary": true }
option:
/*eslint no-unused-expressions: ["error", { "allowTernary": true }]*/
a ? b() : c()
a ? (b = c) : d()
allowShortCircuit 和 allowTernary
¥allowShortCircuit and allowTernary
{ "allowShortCircuit": true, "allowTernary": true }
选项的正确代码示例:
¥Examples of correct code for the { "allowShortCircuit": true, "allowTernary": true }
options:
/*eslint no-unused-expressions: ["error", { "allowShortCircuit": true, "allowTernary": true }]*/
a ? b() || (c = d) : e()
allowTaggedTemplates
{ "allowTaggedTemplates": true }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowTaggedTemplates": true }
option:
/*eslint no-unused-expressions: ["error", { "allowTaggedTemplates": true }]*/
`some untagged template string`;
{ "allowTaggedTemplates": true }
选项的正确代码示例:
¥Examples of correct code for the { "allowTaggedTemplates": true }
option:
/*eslint no-unused-expressions: ["error", { "allowTaggedTemplates": true }]*/
tag`some tagged template string`;
enforceForJSX
JSX 最常用于 React 生态系统,它被编译为 React.createElement
表达式。虽然没有副作用,但这些调用不会被 no-unused-expression
规则自动标记。如果你使用 React 或任何其他无副作用的 JSX pragma,则可以启用此选项来标记这些表达式。
¥JSX is most-commonly used in the React ecosystem, where it is compiled to React.createElement
expressions. Though free from side-effects, these calls are not automatically flagged by the no-unused-expression
rule. If you’re using React, or any other side-effect-free JSX pragma, this option can be enabled to flag these expressions.
{ "enforceForJSX": true }
选项的错误代码示例:
¥Examples of incorrect code for the { "enforceForJSX": true }
option:
/*eslint no-unused-expressions: ["error", { "enforceForJSX": true }]*/
<MyComponent />;
<></>;
{ "enforceForJSX": true }
选项的正确代码示例:
¥Examples of correct code for the { "enforceForJSX": true }
option:
/*eslint no-unused-expressions: ["error", { "enforceForJSX": true }]*/
const myComponentPartial = <MyComponent />;
const myFragment = <></>;
ignoreDirectives
设置为 false
(默认值)时,此规则在使用 ecmaVersion: 3
进行 linting 时将指令(如 "use strict"
)报告为未使用的表达式。存在此默认行为,因为 ES3 环境并不正式支持指令,这意味着此类字符串在特定上下文中实际上是未使用的表达式。
¥When set to false
(default), this rule reports directives (like "use strict"
) as unused expressions when linting with ecmaVersion: 3
. This default behavior exists because ES3 environments do not formally support directives, meaning such strings are effectively unused expressions in that specific context.
将此选项设置为 true
可防止指令被报告为未使用,即使指定了 ecmaVersion: 3
也是如此。此选项主要用于需要维护包含指令的单一代码库,同时支持旧版 ES3 环境和现代 (ES5+) 环境的项目。
¥Set this option to true
to prevent directives from being reported as unused, even when ecmaVersion: 3
is specified. This option is primarily useful for projects that need to maintain a single codebase containing directives while supporting both older ES3 environments and modern (ES5+) environments.
注意:在 ES5+ 环境中,无论此设置如何,指令始终会被忽略。
¥Note: In ES5+ environments, directives are always ignored regardless of this setting.
{ "ignoreDirectives": false }
选项和 ecmaVersion: 3
选项的错误代码示例:
¥Examples of incorrect code for the { "ignoreDirectives": false }
option and ecmaVersion: 3
:
/*eslint no-unused-expressions: ["error", { "ignoreDirectives": false }]*/
"use strict";
"use asm"
"use stricter";
"use babel"
"any other strings like this in the directive prologue";
"this is still the directive prologue";
function foo() {
"bar";
}
{ "ignoreDirectives": true }
选项和 ecmaVersion: 3
选项的正确代码示例:
¥Examples of correct code for the { "ignoreDirectives": true }
option and ecmaVersion: 3
:
/*eslint no-unused-expressions: ["error", { "ignoreDirectives": true }]*/
"use strict";
"use asm"
"use stricter";
"use babel"
"any other strings like this in the directive prologue";
"this is still the directive prologue";
function foo() {
"bar";
}
TypeScript 支持
¥TypeScript Support
此规则支持 TypeScript 特定的表达式,并遵循以下准则:
¥This rule supports TypeScript-specific expressions and follows these guidelines:
-
模块和命名空间声明中允许使用指令(例如
'use strict'
)。¥Directives (like
'use strict'
) are allowed in module and namespace declarations -
如果类型相关的表达式的封装值表达式未使用,则将其视为未使用:
¥Type-related expressions are treated as unused if their wrapped value expressions are unused:
-
类型断言 (
x as number
,<number>x
)¥Type assertions (
x as number
,<number>x
) -
非空断言 (
x!
)¥Non-null assertions (
x!
) -
类型实例化 (
Set<number>
)¥Type instantiations (
Set<number>
)
-
注意:虽然类型表达式永远不会产生运行时副作用(例如,x!
在运行时等同于 x
),但它们可用于断言类型以进行测试。
¥Note: Although type expressions never have runtime side effects (e.g., x!
is equivalent to x
at runtime), they can be used to assert types for testing purposes.
使用 TypeScript 时,此规则的正确代码示例:
¥Examples of correct code for this rule when using TypeScript:
/* eslint no-unused-expressions: "error" */
// Type expressions wrapping function calls are allowed
function getSet() {
return Set;
}
getSet()<number>;
getSet() as Set<unknown>;
getSet()!;
// Directives in modules and namespaces
module Foo {
'use strict';
'hello world';
}
namespace Bar {
'use strict';
export class Baz {}
}
使用 TypeScript 时,此规则的错误代码示例:
¥Examples of incorrect code for this rule when using TypeScript:
/* eslint no-unused-expressions: "error" */
// Standalone type expressions
Set<number>;
1 as number;
window!;
// Expressions inside namespaces
namespace Bar {
123;
}
版本
此规则是在 ESLint v0.1.0 中引入。