首页 > 解决方案 > + 运算符是唯一能够修改字符串同时将其保留为字符串的运算符吗?

问题描述

我正在学习这个 javascript 课程https://javascript.info/operators 我注意到当您使用 *、/、- 等运算符时,字符串不会保留为字符串,而是会被转换。所以我的问题导致了这一点。加号(+)运算符是唯一能够修改字符串并且之后它将保持为字符串的运算符吗?

标签: javascriptstringoperators

解决方案


No, it's not the only operator. There are many that will not type coercion. Depends on how strictly you want to define this, however, in some cases, there is a coercion happening but the end result is the original type.

Here is a list:

Unary operators

delete

The operator can remove properties from objects.

No type coercion is performed but the operation is meaningless. Calling delete on a string literal is a no-op.

"use strict";

delete "hello";
console.log("---")

Calling delete on a variable is a no-op in loose mode but throws an error in strict mode.

"use strict";

let foo = "world";

delete foo;

console.log(foo);

Grouping ()

The grouping operator doesn't change anything about the expression given. It can only change the order of evaluation, if needed. The result of the grouping operator is always the same as the expression inside it.

typeof

It returns the type of the operand given. No type coercion but the output is always a string. In the case of using typeof with primitive strings, the result is always going to be "string".

void

The void operator takes any expression and returns undefined. No type coercion is involved because whatever the value, it is just swallowed.

Binary operators

Assignment operators

Assignment is giving a value to a variable. Some of the assignment operators will not perform coercion, others do.

No coercion: =, +=, ??=, &&=, ||=

No coercion of the assigned value if it's a string. The logical assignments will only conditionally assign the value.

Example:

//`=`, `+=`, `??=`, `&&=`, `||=`

const a = "one";

let b = "t";
b += "wo";

let c = null;
c ??= "three";

let d = true;
d &&= "four";

let e = false;
e ||= "five";

console.log(a, b, c, d, e);


let x = "hello";
x ??= "twenty four";

let y = false;
y &&= "twenty five";

let z = true;
z ||= "twenty six";

console.log(x, y, z);

The addition assignment will work the same as x = x + y which also means that it could coerce to a string, if one of the operands is not that:

let foo = "four";
foo += 2;

let bar = 4;
bar += "two";

console.log(foo, bar);

Coercion is performed: *=, /=, %=, -=, <<=, >>=, >>>=, &=, ^=, |=, **=

All of these will coerce the type of the operand to a number.

Equality

No coercion: ===, !==

The strict equality/inequality operators will not perform any type coercion. If the operands are of different types, the equality check returns false.

With coercion: ==, !=

The loose equality/inequality operators will perform type coercion. How and when depends on the operands given to them. For example, with a string and a number, the string will be coerced to a number. However, with a string and an object, the object will be coerced to a primitive. If that primitive is a number, then the string operand will be coerced again.

See the loose equality algorithm for more information

const a = "   11.";
const b = 11;

console.log("a == b:", a == b);

const c = {
  toString() {
    return "   11.";
  }
}

console.log("a == c:", a == c);

const d = {
  valueOf() {
    return 11;
  }
}

console.log("a == d:", a == d);

const e = {
  [Symbol.toPrimitive]() {
    return "   11.";
  }
}
const f = {
  [Symbol.toPrimitive]() {
    return 11;
  }
}


console.log("a == e:", a == e);
console.log("a == f:", a == f);

Comma ,

The comma operator takes two expressions and returns the second one. No type coercion is involved - it's similar to the void operator in that the value of the first expression is just discarded.

Concatenation +

The addition operator only performs concatenation if at least one of the operands is a string when converted to a primitive. If the other operand does not produce a string, then it's coerced to one:

const a = "1";
const b = 2;

console.log("a + b:", a + b);

const c = {
  toString() {
    return "3";
  }
}

console.log("a + c:", a + c);

const d = {
  valueOf() {
    return 4;
  }
}

console.log("a + d:", a + d);

const e = {
  [Symbol.toPrimitive]() {
    return "5";
  }
}
const f = {
  [Symbol.toPrimitive]() {
    return 6;
  }
}


console.log("a + e:", a + e);
console.log("a + f:", a + f);

//two objects, where one converts to a string
console.log("!!! e + f !!!:", e + f);

Logical Operators ||, &&, ??

The operators will check if the value is truthy or falsy. For strings, only the empty string ("") is falsy, all other strings are truthy. However, the result of the logical operators will not change the type.

const a = true && "one";
const b = false || "two";
const c = null ?? "three";

console.log(a, b, c);

Relational

No coercion: instanceof, in

No coercion involved but some usages are meaningless.

The instanceof operator will never produce true

  • if the right value is a string, it throws an error, as it expects a function.
  • if the left value is a string, then it's not an instance of any other function, since it's a primitive.

Using a non-object as a right value of in also throws an error. It's valid as a left value and no coercion is performed.

Sometimes coercion is performed: <, >, <=, >=

These are similar to + and == in that the operands will sometimes be coerced. With two strings, there is no coercion happening (similar to + and ==) but otherwise an attempt will be made to convert to numbers. Objects are first converted to primitives.

Ternary operators

Conditional operator ? :

A string as first operand will be checked for truthyness. If it's either of the second or third operand, then it's just returned as-is based on the condition.


推荐阅读