For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/stage/2/proposal-math-clamp.md.
  • 简体中文
  • Math.clamp S2

    提案概览
    提案速览

    该提案旨在为 ECMAScript 添加 Math.clamp 函数,用于将值限制在最小值和最大值之间,解决用户区实现中常见的样板代码和潜在错误。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    Math.clamp

    一个 TC39 提案,用于添加 Math.clamp:一个将值限制在上下界之间的函数。

    状态

    阶段: 2
    发起人: Oliver Medhurst (@canadahonk)
    作者: Oliver Medhurst (@canadahonk), Richie Bendall (@richienb)
    上次提出: 第108次会议

    概述和动机

    钳制函数 将值限制在上下界之间。

    我们的主要动机是它在现有项目中的实用性和流行度,在这些项目中,为了可读性,通常会定义该函数。一个常见的用途是动画和交互式内容。例如,它通过限制对象移动的坐标,帮助在用户控制移动期间保持对象在边界内(参见 p5.js 的 constrain 函数的 p5.js 演示)。项目倾向于定义一个看起来像 clamp(number, min, max) 的函数,要么通过:

    • 将数学运算符与 if 语句或三元运算符链式使用
    function clamp(number, minimum, maximum) {
    	if (number < minimum) {
    		return minimum;
    	}
    
    	if (number > maximum) {
    		return maximum;
    	}
    
    	return number;
    }
    function clamp(number, minimum, maximum) {
    	return Math.min(Math.max(number, minimum), maximum);
    }

    这些示例中的每一个都需要不必要的样板代码,并且容易出错。例如,开发人员只需要打错一个运算符或混淆一个变量名,函数就会出错。它们也忽略了当最小值大于最大值,或仅指定了 minmax 时可能发生的未定义行为。

    我们将其命名为函数 clamp,就像其他编程语言中那样...

    ...以及用户空间实现:

    另一个动机是希望与同名的 CSS 函数 保持一致,尽管由于每种上下文中用例略有不同,其参数顺序会有所区别(也参见 关于 CSS clamp 选项顺序的先前讨论

    最初的提案旨在使 minmax 参数可选,并允许 nullundefined 作为值来表示无上界或下界;但根据 最近的 TC39 要求,一些代表同意最好不要这样做,尤其是因为 Math.min/Math.max 仍然可用于单个边界的情况。

    示例

    提议的 API 允许开发人员这样钳制数字:

    Math.clamp(5, 0, 10) // 5
    Math.clamp(-5, 0, 10) // 0
    Math.clamp(15, 0, 10) // 10

    它支持使用 -Infinity/Infinity 来指定没有上界或下界,尽管 Math.min/Math.max 也可以使用:

    Math.clamp(5, 0, Infinity) === Math.max(5, 0) // 5
    Math.clamp(-5, -Infinity, 10) === Math.min(-5, 10) // -5

    如果最小边界大于最大边界,它会抛出 RangeError 以避免开发人员混淆:

    Math.clamp(10, 5, 0) // RangeError

    如果给定 -0,它也会正确尊重 -0

    Math.clamp(-2, -0, 10) // -0
    Math.clamp(-0, -0, 10) // -0
    Math.clamp(0, -0, 10) // 0

    规范

    实现

    致谢

    以往工作: