乐闻世界logo
搜索文章和话题

JS 中应该使用哪个等于运算符 == 和 === ?

7 个月前提问
3 个月前修改
浏览次数117

32个答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

在 JavaScript 中应该使用哪个等于运算符(== 与 ===)来做比较操作?

在 JavaScript 的世界里,比较运算符是我们日常编码中不可或缺的一部分。它们帮助我们理解和判断不同变量或表达式的值是否相等。当我们提到相等比较时,有两个非常相似但又截然不同的运算符:==(相等运算符)和 ===(严格相等运算符)。了解它们的区别,对于写出可靠和高效的代码至关重要。

== 相等运算符:类型强制转换的魔术师

== 运算符在 JavaScript 中被称为“宽松相等”或者“非严格相等”。当使用 == 比较两个值时,如果它们不是同一类型,JavaScript 会尝试类型转换,将它们转换成相同的类型后再做比较。这种类型转换通常被称为“类型强制转换”。

举个栗子 🌰

javascript
0 == '0'; // true,因为字符串 '0' 被强制转换成了数字 0 '1' == 1; // true,同上 null == undefined; // true,null 和 undefined 在非严格相等的情况下被认为是相等的

== 运算符的这种行为可能会引起一些意想不到的结果,有时会导致难以发现的 bug。因此,它经常被认为是 JavaScript 中一种不那么可靠的比较方式。

=== 严格相等运算符:精确无误的严格管家

== 运算符不同,=== 运算符在比较时不会进行类型转换。如果两个值的类型不同,它们就被认为是不相等的。因此,=== 被称为“严格相等”运算符。

再举个栗子 🌰

javascript
0 === '0'; // false,因为它们类型不同:一个是数字,一个是字符串 '1' === 1; // false,同上 null === undefined; // false,null 和 undefined 类型不同

使用 === 运算符可以让你的代码逻辑更加清晰、可预测,并且减少隐藏 bug 的风险。

那么,我们应该怎么选择?

在大多数情况下,推荐使用 === 严格相等运算符,因为它提供了类型安全的比较,能减少许多不必要的问题。当你明确需要进行类型转换时,才考虑使用 ==

最佳实践

假设你在处理一个 web 表单,用户输入的是数字字符串,而你需要将其与数字类型的值进行比较。

javascript
const userInput = '123'; const targetValue = 123; // 使用 ==,因为我们明确知道两边的值应该是相同的,即使类型不同 if (userInput == targetValue) { console.log('用户输入匹配!'); }

在这种情况下,你可能会选择使用 ==,因为它简化了代码。然而,为了保持更好的代码质量和可维护性,你应该考虑显式地转换类型,然后使用 === 进行比较。

javascript
const userInput = '123'; const targetValue = 123; // 显式转换类型,然后使用 === 进行比较 if (Number(userInput) === targetValue) { console.log('用户输入匹配!');
2024年6月29日 12:07 回复

严格相等运算符 ( ===) 的行为与抽象相等运算符 ( ==) 相同,只是不进行类型转换,并且类型必须相同才能被视为相等。

参考:JavaScript 教程:比较运算符

_在进行任何必要的类型转换后,_该==运算符将比较是否相等。该运算符不会进行转换,因此如果两个值不同,类型将简单地返回。两者都同样快。===``===``false

引用 Douglas Crockford 的优秀JavaScript: The Good Parts

JavaScript 有两组相等运算符:===and !==,以及它们的邪恶双胞胎==and !=。好的产品会按照您期望的方式工作。如果两个操作数类型相同且值相同,则===生成true!==生成false。当操作数具有相同类型时,邪恶双胞胎会做正确的事情,但如果它们具有不同类型,它们会尝试强制这些值。他们这样做的规则既复杂又难以记住。以下是一些有趣的案例:

shell
'' == '0' // false 0 == '' // true 0 == '0' // true
shell
false == 'false' // false false == '0' // true
shell
false == undefined // false false == null // false null == undefined // true
shell
' \t\r\n ' == 0 // true

平等比较表

传递性的缺乏令人震惊。我的建议是永远不要使用邪恶的双胞胎。相反,请始终使用===!==。刚刚显示的所有比较都false===运算符有关。


更新

@Casebash在评论和@Phillipe Laybaert 关于对象的 回答中提出了一个很好的观点。对于对象来说,彼此的==行为===一致(特殊情况除外)。

shell
var a = [1,2,3]; var b = [1,2,3]; var c = { x: 1, y: 2 }; var d = { x: 1, y: 2 }; var e = "text"; var f = "te" + "xt"; a == b // false a === b // false c == d // false c === d // false e == f // true e === f // true

特殊情况是当您将一个基元与一个由于其toStringorvalueOf方法而计算结果相同的对象进行比较时。例如,考虑将字符串基元与使用String构造函数创建的字符串对象进行比较。

shell
"abc" == new String("abc") // true "abc" === new String("abc") // false

这里==操作符检查两个对象的值并返回true,但===发现它们的类型不同并返回false。哪一个是正确的?这实际上取决于您要比较的内容。我的建议是完全绕过这个问题,只是不要使用String构造函数从字符串文字创建字符串对象。

参考
https://262.ecma-international.org/5.1/#sec-11.9.3

2024年6月29日 12:07 回复

Using the == operator (Equality)

shell
true == 1; //true, because 'true' is converted to 1 and then compared "2" == 2; //true, because "2" is converted to 2 and then compared

Using the === operator (Identity)

shell
true === 1; //false "2" === 2; //false

This is because the equality operator == does type coercion, meaning that the interpreter implicitly tries to convert the values before comparing.

On the other hand, the identity operator === does not do type coercion, and thus does not convert the values when comparing.

2024年6月29日 12:07 回复

Here's an interesting visualisation of the equality comparison between == and ===.

Source: https://github.com/dorey/JavaScript-Equality-Table (demo, unified demo)


var1 === var2

When using === for JavaScript equality testing, everything is as is.
Nothing gets converted before being evaluated.

JS中===的相等性判断

var1 == var2

When using == for JavaScript equality testing, some funky conversions take place.

JS中==的相等性判断

Summary of equality in Javascript

JavaScript 中的平等


Conclusion:

Always use ===, unless you fully understand the funky conversions that take place with ==.

2024年6月29日 12:07 回复

In the answers here, I didn't read anything about what equal means. Some will say that === means equal and of the same type, but that's not really true. It actually means that both operands reference the same object, or in case of value types, have the same value.

So, let's take the following code:

shell
var a = [1,2,3]; var b = [1,2,3]; var c = a; var ab_eq = (a === b); // false (even though a and b are the same type) var ac_eq = (a === c); // true

The same here:

shell
var a = { x: 1, y: 2 }; var b = { x: 1, y: 2 }; var c = a; var ab_eq = (a === b); // false (even though a and b are the same type) var ac_eq = (a === c); // true

Or even:

shell
var a = { }; var b = { }; var c = a; var ab_eq = (a === b); // false (even though a and b are the same type) var ac_eq = (a === c); // true

This behavior is not always obvious. There's more to the story than being equal and being of the same type.

The rule is:

For value types (numbers):
a === b returns true if a and b have the same value and are of the same type

For reference types:
a === b returns true if a and b reference the exact same object

For strings:
a === b returns true if a and b are both strings and contain the exact same characters


Strings: the special case...

Strings are not value types, but in Javascript they behave like value types, so they will be "equal" when the characters in the string are the same and when they are of the same length (as explained in the third rule)

Now it becomes interesting:

shell
var a = "12" + "3"; var b = "123"; alert(a === b); // returns true, because strings behave like value types

But how about this?:

shell
var a = new String("123"); var b = "123"; alert(a === b); // returns false !! (but they are equal and of the same type)

I thought strings behave like value types? Well, it depends who you ask... In this case a and b are not the same type. a is of type Object, while b is of type string. Just remember that creating a string object using the String constructor creates something of type Object that behaves as a string most of the time.

2024年6月29日 12:07 回复

Let me add this counsel:

If in doubt, read the specification!

ECMA-262 is the specification for a scripting language of which JavaScript is a dialect. Of course in practice it matters more how the most important browsers behave than an esoteric definition of how something is supposed to be handled. But it is helpful to understand why new String("a") !== "a".

Please let me explain how to read the specification to clarify this question. I see that in this very old topic nobody had an answer for the very strange effect. So, if you can read a specification, this will help you in your profession tremendously. It is an acquired skill. So, let's continue.

Searching the PDF file for === brings me to page 56 of the specification: 11.9.4. The Strict Equals Operator ( === ), and after wading through the specificationalese I find:

11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:
1. If Type(x) is different from Type(y), return false.
2. If Type(x) is Undefined, return true.
3. If Type(x) is Null, return true.
4. If Type(x) is not Number, go to step 11.
5. If x is NaN, return false.
6. If y is NaN, return false.
7. If x is the same number value as y, return true.
8. If x is +0 and y is −0, return true.
9. If x is −0 and y is +0, return true.
10. Return false.
11. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
12. If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
13. Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false.

Interesting is step 11. Yes, strings are treated as value types. But this does not explain why new String("a") !== "a". Do we have a browser not conforming to ECMA-262?

Not so fast!

Let's check the types of the operands. Try it out for yourself by wrapping them in typeof(). I find that new String("a") is an object, and step 1 is used: return false if the types are different.

If you wonder why new String("a") does not return a string, how about some exercise reading a specification? Have fun!


Aidiakapi wrote this in a comment below:

From the specification

11.2.2 The new Operator:

If Type(constructor) is not Object, throw a TypeError exception.

With other words, if String wouldn't be of type Object it couldn't be used with the new operator.

new always returns an Object, even for String constructors, too. And alas! The value semantics for strings (see step 11) is lost.

And this finally means: new String("a") !== "a".

2024年6月29日 12:07 回复

I tested this in Firefox with Firebug using code like this:

shell
console.time("testEquality"); var n = 0; while (true) { n++; if (n == 100000) break; } console.timeEnd("testEquality");

Run code snippetHide results

Expand snippet

and

shell
console.time("testTypeEquality"); var n = 0; while (true) { n++; if (n === 100000) break; } console.timeEnd("testTypeEquality");

Run code snippetHide results

Expand snippet

My results (tested five times each and averaged):

shell
==: 115.2 ===: 114.4

So I'd say that the miniscule difference (this is over 100000 iterations, remember) is negligible. Performance isn't a reason to do ===. Type safety (well, as safe as you're going to get in JavaScript), and code quality is.

2024年6月29日 12:07 回复

In PHP and JavaScript, it is a strict equality operator. Which means, it will compare both type and values.

2024年6月29日 12:07 回复

In JavaScript it means of the same value and type.

For example,

shell
4 == "4" // will return true

but

shell
4 === "4" // will return false
2024年6月29日 12:07 回复

为什么 == 这么难以预测?

当你将空字符串 "" 与数字零 0 进行比较时,会得到什么结果?

true

没错,根据 == 的规则,一个空字符串和数字零被认为是相同的。

但这还不是全部。再看这个例子:

shell
'0' == false // true

数组的情况更加奇怪。

shell
[1] == true // true [] == false // true [[]] == false // true [0] == false // true

字符串的情况则更加怪异

shell
[1,2,3] == '1,2,3' // true - 真的吗?! '\r\n\t' == 0 // true - 这也太扯了吧!

情况还会变得更糟:

什么时候相等不等于相等?

shell
let A = '' // 空字符串 let B = 0 // 数字零 let C = '0' // 字符串中的零 A == B // true - 好吧... B == C // true - 到目前为止还不错... A == C // **FALSE** - 情节转折!

我们再来看一遍:

shell
(A == B) && (B == C) // true (A == C) // **FALSE**

这些疯狂的事情只发生在原始类型上。

当你使用 == 来比较对象时,情况会变得完全不同。

这时你可能会想...

为什么会这样发生?

这是因为不像 "三等号"(===)只检查两个值是否完全相同。

== 做了一大堆其他的事情

它对待函数、null、undefined、字符串等都有特殊处理。

事情变得相当混乱。

事实上,如果你尝试编写一个执行 == 相同操作的函数,它可能看起来像这样:

javascript
function isEqual(x, y) { // 如果 `==` 是一个函数 if (typeof y === typeof x) return y === x; // 将 null 和 undefined 视为相同 var xIsNothing = (y === undefined) || (y === null); var yIsNothing = (x === undefined) || (x === null); if (xIsNothing || yIsNothing) return (xIsNothing && yIsNothing); if (typeof y === "function" || typeof x === "function") { // 如果任一值是字符串 // 将函数转换为字符串并比较 if (typeof x === "string") { return x === y.toString(); } else if (typeof y === "string") { return x.toString() === y; } return false; } if (typeof x === "object") x = toPrimitive(x); if (typeof y === "object") y = toPrimitive(y); if (typeof y === typeof x) return y === x; // 如果 x 和 y 不是数字,则将它们转换为数字 if (typeof x !== "number") x = +x; if (typeof y !== "number") y = +y; // 实际上真正的 `==` 比这还要复杂,尤其是在ES6中 return x === y; } function toPrimitive(obj) { var value = obj.valueOf(); if (value !== obj) return value; return obj.toString(); }

这意味着什么?

意味着 == 很复杂。

因为它复杂,所以很难知道在使用它时会发生什么。

这意味着你可能会遇到bug。

故事的寓意是...

让你的生活变得简单些。

使用 === 而不是 ==

故事结束。

2024年6月29日 12:07 回复

The === operator is called a strict comparison operator, it does differ from the == operator.

Lets take 2 vars a and b.

For "a == b" to evaluate to true a and b need to be the same value.

In the case of "a === b" a and b must be the same value and also the same type for it to evaluate to true.

Take the following example

shell
var a = 1; var b = "1"; if (a == b) //evaluates to true as a and b are both 1 { alert("a == b"); } if (a === b) //evaluates to false as a is not the same type as b { alert("a === b"); }

In summary; using the == operator might evaluate to true in situations where you do not want it to so using the === operator would be safer.

In the 90% usage scenario it won't matter which one you use, but it is handy to know the difference when you get some unexpected behaviour one day.

2024年6月29日 12:07 回复

=== checks same sides are equal in type as well as value.


Example:

shell
'1' === 1 // will return "false" because `string` is not a `number`

Common example:

shell
0 == '' // will be "true", but it's very common to want this check to be "false"

Another common example:

shell
null == undefined // returns "true", but in most cases a distinction is necessary

From my long-time experience an untyped check is preferable because you do not care if the value is either undefined, null, 0 or ""

Another comparison approach is using Object.is and here's a great informative answer about it.

2024年6月29日 12:07 回复

Javascript execution flow diagram for strict equality / Comparison '==='

Javascript strict equality

Javascript execution flow diagram for non strict equality / comparison '=='

Javascript non equality

2024年6月29日 12:07 回复

JavaScript === vs == .

shell
0==false // true 0===false // false, because they are of a different type 1=="1" // true, auto type coercion 1==="1" // false, because they are of a different type
2024年6月29日 12:07 回复

It means equality without type coercion type coercion means JavaScript do not automatically convert any other data types to string data types

shell
0==false // true,although they are different types 0===false // false,as they are different types 2=='2' //true,different types,one is string and another is integer but javaScript convert 2 to string by using == operator 2==='2' //false because by using === operator ,javaScript do not convert integer to string 2===2 //true because both have same value and same types
2024年6月29日 12:07 回复

In a typical script there will be no performance difference. More important may be the fact that thousand "===" is 1 KB heavier than thousand "==" :) JavaScript profilers can tell you if there is a performance difference in your case.

But personally I would do what JSLint suggests. This recommendation is there not because of performance issues, but because type coercion means ('\t\r\n' == 0) is true.

2024年6月29日 12:07 回复

The equal comparison operator == is confusing and should be avoided.

If you HAVE TO live with it, then remember the following 3 things:

  1. It is not transitive: (a == b) and (b == c) does not lead to (a == c)
  2. It's mutually exclusive to its negation: (a == b) and (a != b) always hold opposite Boolean values, with all a and b.
  3. In case of doubt, learn by heart the following truth table:

EQUAL OPERATOR TRUTH TABLE IN JAVASCRIPT

  • Each row in the table is a set of 3 mutually "equal" values, meaning that any 2 values among them are equal using the equal == sign*

** STRANGE: note that any two values on the first column are not equal in that sense.**

shell
'' == 0 == false // Any two values among these 3 ones are equal with the == operator '0' == 0 == false // Also a set of 3 equal values, note that only 0 and false are repeated '\t' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '\r' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '\n' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '\t\r\n' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- null == undefined // These two "default" values are not-equal to any of the listed values above NaN // NaN is not equal to any thing, even to itself.
2024年6月29日 12:07 回复

There is unlikely to be any performance difference between the two operations in your usage. There is no type-conversion to be done because both parameters are already the same type. Both operations will have a type comparison followed by a value comparison.

2024年6月29日 12:07 回复

Simply

== means comparison between operands with type coercion

and

=== means comparison between operands without type coercion.

Type coercion in JavaScript means automatically converting data types to other data types.

For example:

shell
123 == "123" // Returns true, because JS coerces string "123" to number 123 // and then goes on to compare `123 == 123`. 123 === "123" // Returns false, because JS does not coerce values of different types here.
2024年6月29日 12:07 回复

Yes! It does matter.

=== operator in javascript checks value as well as type where as == operator just checks the value (does type conversion if required).

enter image description here

You can easily test it. Paste following code in an HTML file and open it in browser

shell
<script> function onPageLoad() { var x = "5"; var y = 5; alert(x === 5); }; </script> </head> <body onload='onPageLoad();'>

You will get 'false' in alert. Now modify the onPageLoad() method to alert(x == 5); you will get true.

2024年6月29日 12:07 回复

As a rule of thumb, I would generally use === instead of == (and !== instead of !=).

Reasons are explained in in the answers above and also Douglas Crockford is pretty clear about it (JavaScript: The Good Parts).

However there is one single exception: == null is an efficient way to check for 'is null or undefined':

shell
if( value == null ){ // value is either null or undefined }

For example jQuery 1.9.1 uses this pattern 43 times, and the JSHint syntax checker even provides the eqnull relaxing option for this reason.

From the jQuery style guide:

Strict equality checks (===) should be used in favor of ==. The only exception is when checking for undefined and null by way of null.

shell
// Check for both undefined and null values, for some important reason. undefOrNull == null;

EDIT 2021-03:

Nowadays most browsers support the Nullish coalescing operator (??) and the Logical nullish assignment (??=), which allows a more concise way to assign a default value if a variable is null or undefined, for example:

shell
if (a.speed == null) { // Set default if null or undefined a.speed = 42; }

can be written as any of these forms

shell
a.speed ??= 42; a.speed ?? a.speed = 42; a.speed = a.speed ?? 42;
2024年6月29日 12:07 回复

It's a strict check test.

It's a good thing especially if you're checking between 0 and false and null.

For example, if you have:

shell
$a = 0;

Then:

shell
$a==0; $a==NULL; $a==false;

All returns true and you may not want this. Let's suppose you have a function that can return the 0th index of an array or false on failure. If you check with "==" false, you can get a confusing result.

So with the same thing as above, but a strict test:

shell
$a = 0; $a===0; // returns true $a===NULL; // returns false $a===false; // returns false
2024年6月29日 12:07 回复

=== operator checks the values as well as the types of the variables for equality.

== operator just checks the value of the variables for equality.

2024年6月29日 12:07 回复

JSLint sometimes gives you unrealistic reasons to modify stuff. === has exactly the same performance as == if the types are already the same.

It is faster only when the types are not the same, in which case it does not try to convert types but directly returns a false.

So, IMHO, JSLint maybe used to write new code, but useless over-optimizing should be avoided at all costs.

Meaning, there is no reason to change == to === in a check like if (a == 'test') when you know it for a fact that a can only be a String.

Modifying a lot of code that way wastes developers' and reviewers' time and achieves nothing.

2024年6月29日 12:07 回复

A simple example is

shell
2 == '2' -> true, values are SAME because of type conversion. 2 === '2' -> false, values are NOT SAME because of no type conversion.
2024年6月29日 12:07 回复

The top 2 answers both mentioned == means equality and === means identity. Unfortunately, this statement is incorrect.

If both operands of == are objects, then they are compared to see if they are the same object. If both operands point to the same object, then the equal operator returns true. Otherwise, the two are not equal.

shell
var a = [1, 2, 3]; var b = [1, 2, 3]; console.log(a == b) // false console.log(a === b) // false

In the code above, both == and === get false because a and b are not the same objects.

That's to say: if both operands of == are objects, == behaves same as ===, which also means identity. The essential difference of this two operators is about type conversion. == has conversion before it checks equality, but === does not.

2024年6月29日 12:07 回复

The problem is that you might easily get into trouble since JavaScript have a lot of implicit conversions meaning...

shell
var x = 0; var isTrue = x == null; var isFalse = x === null;

Which pretty soon becomes a problem. The best sample of why implicit conversion is "evil" can be taken from this code in MFC / C++ which actually will compile due to an implicit conversion from CString to HANDLE which is a pointer typedef type...

shell
CString x; delete x;

Which obviously during runtime does very undefined things...

Google for implicit conversions in C++ and STL to get some of the arguments against it...

2024年6月29日 12:07 回复

From the core javascript reference

=== Returns true if the operands are strictly equal (see above) with no type conversion.

2024年6月29日 12:07 回复

Equality comparison:

Operator ==

Returns true, when both operands are equal. The operands are converted to the same type before being compared.

shell
>>> 1 == 1 true >>> 1 == 2 false >>> 1 == '1' true

Equality and type comparison:

Operator ===

Returns true if both operands are equal and of the same type. It's generally better and safer if you compare this way, because there's no behind-the-scenes type conversions.

shell
>>> 1 === '1' false >>> 1 === 1 true
2024年6月29日 12:07 回复

Here is a handy comparison table that shows the conversions that happen and the differences between == and ===.

As the conclusion states:

"Use three equals unless you fully understand the conversions that take place for two-equals."

http://dorey.github.io/JavaScript-Equality-Table/

2024年6月29日 12:07 回复

在JavaScript中,nullundefined 都代表不存在的值,即:

javascript
var a; // a被声明了,但没有赋值,其值为undefined var b = null; // b被赋予了null,表示一个空值

这里变量 ab 都没有具体的值。相对地,0、false 和空字符串 '' 虽然代表各自的值,但它们有一个共同点:都被认为是假值(falsy value),也就是说,在条件判断中它们都会被当作 false

据此,0、false'' 可以看作是一组特殊的假值。而 nullundefined 则构成另一组特殊的无值。查看下面的比较图,nullundefined 在JavaScript中被认为是相等的。同理,0、false'' 也被认为彼此相等。尽管如此,它们在JavaScript中都符合假值的条件。

在此输入图像描述

与此相对,任何对象(如 {} 和数组等)、非空字符串以及布尔值 true 都被视为真值(truthy value),在条件判断中它们相当于 true。但是,这些真值并不意味着它们之间相等。

2024年6月29日 12:07 回复

在 JavaScript 中,你通常应该使用 === (严格等于) 运算符来进行比较操作,而不是 == (宽松等于) 运算符。

=== (严格等于) 运算符会比较两个值的类型和值,只有当两者都相等时,它才会返回 true。这意味着如果两个值的类型不同,它们永远不会被认为是严格相等的。

javascript
3 === '3' // false,因为一个是数字类型,另一个是字符串类型

== (宽松等于) 运算符会在比较之前将两个值进行类型转换(如果它们的类型不同的话),然后再比较它们的值。

javascript
3 == '3' // true,因为字符串 '3' 会被转换成数字 3

使用 === 可以避免由 JavaScript 自动类型转换导致的潜在错误和混淆,因此它通常是一个更好的选择。然而,必须指出在某些罕见情况下,如果你确实需要进行类型转换,那么使用 == 也是合适的。但在多数情况下,推荐使用 === 来确保代码的准确性和清晰性。

2024年6月29日 12:07 回复

你的答案