2 ** 3 ** 2 等于多少?90% 的人第一眼都算错

27 阅读4分钟



有一次我加班到凌晨,咖啡一杯接一杯。

第一杯,精神回来了;

第二杯,手速起飞;

第三杯,感觉自己能写完一个中台;

第四杯……心跳开始报警。

我突然意识到:有些东西不是线性增长的,而是指数级爆炸的。

技术世界里也是这样。你以为只是“再乘一次”,但结果已经完全不是一个量级了。而 JavaScript 里的指数操作符,本质上讲的,就是这个故事。

什么是指数?先别急着写代码

如果你刚入行的时候,数学不太好(比如我),那“指数”两个字可能自带压力。但换个说法你就懂了。

假设你有 1 块钱:

  • 第一天翻 1 倍:2 块
  • 第二天再翻 1 倍:4 块
  • 第三天再翻 1 倍:8 块

这不是“加钱”,而是每一步都在“复制自己” 。数学上我们写成:

而在 JavaScript 里,以前我们只能这样写:

直到有一天,ECMAScript 说了一句非常人性化的话:“程序员,别受委屈了,给你一个专门的操作符吧。”

于是,指数操作符 ** 登场了。

指数操作符 **,长什么样?

一句话版本:

表示:a 的 b 次方

举几个最直观的例子:

如果你是第一次看到它,可能会觉得:“这不是 Python 吗?”

没错,JavaScript 终于在这件事上,和 Python 达成了“友好外交”。

小米的比喻:指数操作符像“复制机”

我一直觉得,** 很像一个复制机

  • 2 ** 3: 把 2 复制 3 次,然后一股脑乘起来
  • 5 ** 1: 复制一次,本质还是自己
  • 5 ** 0: 一次都不复制?那就给你一个“默认存在值1”

这也解释了很多新手常问的问题:

“0 不是啥都没有吗?怎么还等于 1?”,从数学和编程实现角度看:0 次方的核心含义不是‘乘’,而是‘不参与’。

** 和 Math.pow,到底该用谁?

这是一个非常经典的“社招面试题衍生问”。我们先直接对比:

从结果看,完全一样。那差别在哪?

1、可读性

更接近“人类语言”。

2、运算符优先级

** 是真正的操作符,可以自然参与表达式计算:

如果是 Math.pow,你通常得多写点括号。

3、兼容性(历史问题)

早期浏览器不支持 **,但现在已经不是问题了。现代前端项目,放心用。

4、结论一句话

**新代码优先 ,老项目维护 Math.pow。

一个很容易踩坑的点:右结合性

重点来了,这是指数操作符最“坑新手”的地方。先看这行代码:

你觉得结果是多少?很多人第一反应是:

但真实结果是:

为什么?因为:指数操作符是“右结合”的。 也就是说:

生活比喻:指数就像“代言人签合同”,先签最里面那一层,再往外扩散。

所以,写指数表达式时,我的建议是:宁可多写括号,也别赌同事的数学水平。

指数操作符 + 负数,会发生什么?

指数和负数一结合,就开始有点“理工味”了。

这表示什么?数学上:

再来一个:

等价于:

指数的负数,本质就是“倒数的指数”。

指数操作符和一元负号,优先级陷阱

来看一个经典“面试杀手”:

你以为是:

但实际结果是:

为什么?因为在 JavaScript 里: **** 的优先级高于一元负号。**

正确写法应该是:

这也是为什么很多规范会建议:只要指数参与负数运算,一定加括号。

在真实业务里,** 用在哪?

你可能会问:“指数听着很学术,真实项目里用得多吗?”

答案是:比你想象得多。

1、动画与缓动函数

很多动画的“先慢后快”“先快后慢”,底层就是指数或幂函数。

2、权重计算

搜索、推荐、排序算法里,经常用指数放大差异:

3、金融、增长模型

复利计算,本质就是指数。

总结

如果让我用一句话总结 JavaScript 的指数操作符: **** 是一个让“增长速度失控”的操作符。**

它看起来只是两个小星号,但背后代表的是:

  • 非线性思维
  • 数量级跃迁
  • 和数学世界的直接连接

如果你还停留在 Math.pow,那只是能用;如果你真正理解 ****** ,那是开始驾驭表达式了

END

下次你在代码里看到 a ** b,别急着写完就走,想一秒钟: “这是线性增长,还是指数爆炸?”

想清楚这一点,你已经比昨天的自己,又强了一点点。

好朋友们,我们下篇见。

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!