关于`1 + - + + + - + 1;`的理解(一元操作符 + - 的理解)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39759115/article/details/80074523

节选

下面部分节选自:《你不懂JS:类型与文法》第四章:强制转换中的 “明确地:Strings <–> Numbers”

除了String(..)和Number(..),还有其他的方法可以把这些值在string和number之间进行“明确地”转换:

var a = 42;
var b = a.toString();

var c = "3.14";
var d = +c;

b; // "42"
d; // 3.14

调用 a.toString() 在表面上是明确的(“toString”意味着“变成一个字符串”是很明白的),但是这里有一些藏起来的隐含性。toString() 不能在像 42 这样的 基本类型 值上调用。所以JS会自动地将42“封箱”在一个对象包装器中,这样toString()就可以针对这个对象调用。换句话讲,你可能会叫它“明确的隐含”。

这里的+c+操作符的 一元操作符(操作符只有一个操作数)形式。取代进行数学加法(或字符串连接 —— 见下面的讨论)的是,一元的+明确地将它的操作数(c)强制转换为一个number值。

+c明确的 强制转换吗?这要看你的经验和角度。如果你知道(现在你知道了!)一元+明确地意味着number强制转换,那么它就是相当明确和明显的。但是,如果你以前从没见过它,那么它看起来就极其困惑,晦涩,带有隐含的副作用,等等。

注意: 在开源的JS社区中一般被接受的观点是,一元+是一个 明确的 强制转换形式。

即使你真的喜欢+c这种形式,它绝对会在有的地方看起来非常令人困惑。考虑下面的代码:

var c = "3.14";
var d = 5+ +c;

d; // 8.14

一元-操作符也像+一样进行强制转换,但它还会翻转数字的符号。但是你不能放两个减号--来使符号翻转回来,因为那将被解释为递减操作符。取代它的是,你需要这么做:- -"3.14",在两个减号之间加入空格,这将会使强制转换的结果为3.14

这里有另一个疯狂的例子( 一个二元操作符挨着另一个操作符的一元形式):

1 + - + + + - + 1;  // 2

当一个一元+(或-)紧邻其他操作符时,你应当强烈地考虑避免使用它。虽然上面的代码可以工作,但几乎全世界都认为它是一个坏主意。即使是d = +c(或者d =+ c!)都太容易与d += c像混淆了,而后者完全是不同的东西!

注意: 一元+的另一个极端使人困惑的地方是,被用于紧挨着另一个将要作为++递增操作符和--递减操作符的操作数。例如:a +++ba + ++b,和a + + +b。更多关于++的信息,参见第五章的“表达式副作用”。

记住,我们正努力变得明确并 减少 困惑,不是把事情弄得更糟!

理解

关于 1 + - + + + - + 1; 看到的第一印象是很懵的这个要怎么去理解????

后来反复阅读上面的节选部分内容,找到了关键的一句换:

一元-操作符也像+一样进行强制转换,但它还会翻转数字的符号。

也就是说:

一元+操作符会把字符串强制转换为数字

一元-操作符不仅会把字符串强制转换为数字,还会翻转数字的符号 — 即改变数字的正负

现在再来看这行代码 1 + - + + + - + 1;

可以粗略的把它分为三个部分:数字1、加法运算符 + 以及强制转换部分- + + + - + 1

根据刚刚理解的转换规则,在看强制转换部分的时候可以把+ 暂时忽略(一元+操作符只会把字符串强制转换为数字),那么只剩下 - - 1 ,所以可以很快的得出强制转换的结果为 1- 为奇数符号改变,为偶数符号不变),整行代码运行的结果为2

下面这些也就很好理解了:

1 + - 1;                   // 0
1 + - + + + + - 1;         // 2
1 + - + + + - - 1;         // 0
1 + - + + + - + + 1;       // 2
1 + - + + + + - - + + 1;   // 0
1 + - + + + +  - + + 1;    // 2

猜你喜欢

转载自blog.csdn.net/qq_39759115/article/details/80074523