recursal/MDN huggingface dataset:
Number.prototype.toPrecision()
==============================

`Number` 值的 **`toPrecision()`** 方法返回一个以指定精度表示该数字的字符串。

尝试一下
----

语法
--


```js
toPrecision()
toPrecision(precision)
```

### 参数

`precision` 可选

一个指定有效位数的整数。

### 返回值

一个以定点表示法或指数表示法表示 `Number` 对象的字符串，该字符串四舍五入到 `precision` 个有效数字。有关四舍五入的讨论，请参阅 `Number.prototype.toFixed()` 方法的描述，其也适用于 `toPrecision()`。

如果 `precision` 参数被省略，则与 `Number.prototype.toString()` 行为相同。如果 `precision` 参数不是整数，则将其四舍五入到最近的整数。

### 异常

`RangeError`

如果 `precision` 不在 `1` 和 `100` 之间（包含两端），则抛出该错误。

示例
--

### 使用 `toPrecision`


```js
let numObj = 5.123456;

console.log(numObj.toPrecision()); // 输出 '5.123456'
console.log(numObj.toPrecision(5)); // 输出 '5.1235'
console.log(numObj.toPrecision(2)); // 输出 '5.1'
console.log(numObj.toPrecision(1)); // 输出 '5'

numObj = 0.000123;

console.log(numObj.toPrecision()); // 输出 '0.000123'
console.log(numObj.toPrecision(5)); // 输出 '0.00012300'
console.log(numObj.toPrecision(2)); // 输出 '0.00012'
console.log(numObj.toPrecision(1)); // 输出 '0.0001'

// 请注意，在某些情况下可能会返回指数表示法字符串
console.log((1234.5).toPrecision(2)); // 输出 '1.2e+3'
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.prototype.toprecision |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Number.prototype.toFixed()`
* `Number.prototype.toExponential()`
* `Number.prototype.toString()`
Number.prototype.toFixed()
==========================

`Number` 值的 **`toFixed()`** 方法使用定点表示法来格式化该数值。

尝试一下
----

语法
--


```js
toFixed()
toFixed(digits)
```

### 参数

`digits` 可选

小数点后的位数。应该是一个介于 `0` 和 `100` 之间的值，包括 `0` 和 `100`。如果这个参数被省略，则被视为 `0`。

### 返回值

使用定点表示法表示给定数字的字符串。

### 异常

`RangeError`

如果 `digits` 不是介于 `0` 和 `100` 之间（含两端）的值，则抛出该异常。

`TypeError`

如果不是在 `Number` 上调用该方法，则抛出该异常。

描述
--

`toFixed()` 方法返回一个表示 `numObj` 的字符串，但不使用指数计数法，并且小数点后有精确到 `digits` 位的数字。如果需要截断，则将数字四舍五入；如果小数位数不足，则小数部分用零填充，以使其具有指定长度。

如果 `numObj` 的绝对值大于或等于 1021，则该方法使用与 `Number.prototype.toString()` 相同的算法，并以指数计数法返回字符串。如果 `numObj` 的值不是有限的，则 `toFixed()` 会返回 `"Infinity"`、`"NaN"` 或 `"-Infinity"`。

`toFixed()` 对于某些值可能具有比 `toString` 更加精确的输出，因为 `toString()` 只输出足够的有效数字来区分该数值与邻近的数值。例如：


```js
(1000000000000000128).toString(); // '1000000000000000100'
(1000000000000000128).toFixed(0); // '1000000000000000128'
```


然而，选择一个过高的 `digits` 精度会导致意外的结果，因为小数部分的数字不能精确地表示成浮点数。例如：


```js
(0.3).toFixed(50); // '0.29999999999999998889776975374843459576368331909180'
```

示例
--

### 使用 toFixed()


```js
const numObj = 12345.6789;

numObj.toFixed(); // '12346'；四舍五入，没有小数部分
numObj.toFixed(1); // '12345.7'；向上舍入
numObj.toFixed(6); // '12345.678900'；用零补足位数
(1.23e20).toFixed(2); // '123000000000000000000.00'
(1.23e-10).toFixed(2); // '0.00'
(2.34).toFixed(1); // '2.3'
(2.35).toFixed(1); // '2.4'；向上舍入
(2.55).toFixed(1); // '2.5'
// 它向下舍入，因为它无法用浮点数精确表示，并且最接近的可表示浮点数较小
(2.449999999999999999).toFixed(1); // '2.5'
// 向上舍入，因为它与 2.45 的差值小于 Number.EPSILON。
// 这个字面量实际上编码和 2.45 相同的数值

(6.02 \* 10 \*\* 23).toFixed(50); // 6.019999999999999e+23；大数仍然使用指数表示法
```

### 对负数使用 toFixed()

由于成员访问的优先级高于一元减号，你需要将负数表达式组合以获得一个字符串。


```js
-2.34.toFixed(1); // -2.3，数字
(-2.34).toFixed(1); // '-2.3'
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.prototype.tofixed |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Number.prototype.toExponential()`
* `Number.prototype.toPrecision()`
* `Number.prototype.toString()`
* `Number.EPSILON`
Number() 构造函数
=============

**`Number()`** 构造函数创建 `Number` 对象。当作为函数调用时，它返回 Number 类型的原始值。

语法
--


```js
new Number(value)
Number(value)
```


**备注：** 调用 `Number()` 时可以使用或不使用 `new`，但是效果不同。详见返回值部分。

### 参数

`value`

所创建对象的数值。

### 返回值

当 `Number` 作为构造函数调用（使用 `new`）时，它创建一个 `Number` 对象，这个对象**不是**原始值。

当 `Number` 作为普通函数调用时，它将参数强制转换为数字原始值。BigInt 被转换为数字。如果值不能转换，则返回 `NaN`。

**警告：** 你会发现你很少会使用 `Number` 作为构造函数。

示例
--

### 创建 Number 对象


```js
const a = new Number("123"); // a === 123 为 false
const b = Number("123"); // b === 123 为 true
a instanceof Number; // 为 true
b instanceof Number; // 为 false
typeof a; // "object"
typeof b; // "number"
```

### 使用 Number() 将 BigInt 转换为数字

`Number()` 是唯一可以将 BigInt 转换为数字而不抛出错误的情况，因为这是完全显式的转换。


```js
+1n; // TypeError: Cannot convert a BigInt value to a number
0 + 1n; // TypeError: Cannot mix BigInt and other types, use explicit conversions
```



```js
Number(1n); // 1
```


注意，如果 BigInt 非常大，以至于不能安全地表示它，这种转换可能会损失精度。


```js
BigInt(Number(2n \*\* 54n + 1n)) === 2n \*\* 54n + 1n; // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number-constructor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中现代 `Number` 行为（支持二进制和八进制字面量）的 Polyfill
* `NaN`
* `Math`
* `BigInt`
Number.prototype.valueOf()
==========================

`Number` 值的 **`valueOf()`** 方法返回该数字的值。

尝试一下
----

语法
--


```js
valueOf()
```

### 参数

无。

### 返回值

一个表示指定 `Number` 对象的原始值的数字。

描述
--

该方法通常由 JavaScript 在内部调用，而非在 Web 代码中显式调用。

示例
--

### 使用 valueOf


```js
const numObj = new Number(10);
console.log(typeof numObj); // object

const num = numObj.valueOf();
console.log(num); // 10
console.log(typeof num); // number
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.prototype.valueof |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.prototype.valueOf()`
Number.isFinite()
=================

**`Number.isFinite()`** 静态方法判断传入值是否是一个有限数——也就是说，它检查给定值是一个数字，且该数字既不是正的 `Infinity`，也不是负的 `Infinity` 或 `NaN`。

尝试一下
----

语法
--


```js
Number.isFinite(value)
```

### 参数

`value`

要测试有限性的值。

### 返回值

如果给定值是有限数，则返回布尔值 `true`。否则为 `false`。

示例
--

### 使用 isFinite()


```js
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false
Number.isFinite(-Infinity); // false

Number.isFinite(0); // true
Number.isFinite(2e64); // true
```

### Number.isFinite() 和全局 isFinite() 之间的不同

与全局 `isFinite()` 函数相比，此方法不会先将参数转换为数字，这意味着只有类型为数字*且*为有限数的值才返回 `true`，而非数字的值始终返回 `false`。


```js
isFinite("0"); // true；强制转换为数字 0
Number.isFinite("0"); // false
isFinite(null); // true；强制转换为数字 0
Number.isFinite(null); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.isfinite |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Number.isFinite` 的 polyfill
* `Number`
* `isFinite()`
Number.MIN\_VALUE
=================

**`Number.MIN_VALUE`** 静态数据属性表示在 JavaScript 中可表示的最小正数值。

尝试一下
----

值
-

2-1074，或 `5E-324`。

| `Number.MIN_VALUE` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

`Number.MIN_VALUE` 是能够在浮点精度范围内表示的最小正数（不是最小负数），换句话说，它是最接近 0 的数。ECMAScript 规范并没有定义引擎实现必须支持的精确值，而是规定：*“必须是实现实际上可以表示的最小非零正值”*。这是因为小的 IEEE-754 浮点数是非正规数，但是实现并不要求支持这种表示方式，这种情况下 `Number.MIN_VALUE` 可能会更大。

在实践中，在主流引擎（如 Chrome、Edge、Node.js 使用的 V8 引擎，Firefox 使用的 SpiderMonkey 引擎，以及 Safari 使用的 JavaScriptCore 引擎）中，`Number.MIN_VALUE` 的精确值为 2-1074，即 `5E-324`。

由于 `MIN_VALUE` 是 `Number` 对象的静态属性，你应该始终将其用作 `Number.MIN_VALUE`，而不是作为一个数字值的属性。

示例
--

### 使用 MIN\_VALUE

下面的代码对两个数值进行除法运算。如果结果大于或等于 `MIN_VALUE`，则调用函数 `func1`；否则，调用函数 `func2`。


```js
if (num1 / num2 >= Number.MIN\_VALUE) {
  func1();
} else {
  func2();
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.min\_value |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Number.MAX_VALUE`
Number.MIN\_SAFE\_INTEGER
=========================

**`Number.MIN_SAFE_INTEGER`** 静态数据属性代表在 JavaScript 中最小的安全整数（-253 – 1）。

要表示比这小的整数，请考虑使用 `BigInt`。

尝试一下
----

值
-

`-9007199254740991`（-9,007,199,254,740,991，或大约 -9 千万亿）。

| `Number.MIN_SAFE_INTEGER` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

双精度浮点格式只有 52 位用于表示尾数，因此它只能安全地表示介于 -(253 – 1) 和 253 – 1 之间的整数。本文中，“安全”指的是能够精确表示整数并正确比较它们。例如，`Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGER - 2` 的结果将为真，这在数学上是不正确的。有关更多信息，请参阅 `Number.isSafeInteger()`。

由于 `MIN_SAFE_INTEGER` 是 `Number` 的静态属性，你应该始终将其使用为 `Number.MIN_SAFE_INTEGER`，而不是一个数字值的属性。

示例
--

### 使用 MIN\_SAFE\_INTEGER


```js
Number.MIN\_SAFE\_INTEGER; // -9007199254740991
-(2 \*\* 53 - 1); // -9007199254740991
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.min\_safe\_integer |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Number.MIN_SAFE_INTEGER` 的 polyfill
* `Number.MAX_SAFE_INTEGER`
* `Number.isSafeInteger()`
* `BigInt`
Number.NEGATIVE\_INFINITY
=========================

**`Number.NEGATIVE_INFINITY`** 静态数据属性表示负无穷值。

尝试一下
----

值
-

与全局属性 `Infinity` 的负值相同。

| `Number.NEGATIVE_INFINITY` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

`Number.NEGATIVE_INFINITY` 的表现同数学上的无穷大略有不同：

* 任何正值，包括 `POSITIVE_INFINITY`，乘以 `NEGATIVE_INFINITY` 等于 `NEGATIVE_INFINITY`。
* 任何负值，包括 `NEGATIVE_INFINITY`，乘以 `POSITIVE_INFINITY` 等于 `POSITIVE_INFINITY`。
* 任何正值除以 `NEGATIVE_INFINITY` 都是负零（正如 IEEE 754 中所定义的）。
* 任何负值除以 `NEGATIVE_INFINITY` 都是正零（正如 IEEE 754 中所定义的）。
* 零除以 `NEGATIVE_INFINITY` 等于 `NaN`。
* `NaN` 乘以 `NEGATIVE_INFINITY` 等于 `NaN`。
* `NEGATIVE_INFINITY`，除以任何负值（除了 `NEGATIVE_INFINITY`），都等于 `POSITIVE_INFINITY`。
* `POSITIVE_INFINITY`，除以任何正值（除了 `POSITIVE_INFINITY`），都等于 `NEGATIVE_INFINITY`。
* `NEGATIVE_INFINITY`，除以 `NEGATIVE_INFINITY` 或 `POSITIVE_INFINITY`，都等于 `NaN`。
* `x > Number.NEGATIVE_INFINITY` 对于任何不是 `NEGATIVE_INFINITY` 的数字 *x* 都为真。

你可以使用 `Number.NEGATIVE_INFINITY` 属性来表示成功时返回有限数值的错误条件。不过，`NaN` 更适合于这种情况。

由于 `NEGATIVE_INFINITY` 是 `Number` 的静态属性，你应该始终将其用作 `Number.NEGATIVE_INFINITY`，而不是作为一个数字值的属性。

示例
--

### 使用 NEGATIVE\_INFINITY

在下面的例子中，变量 `smallNumber` 被赋值为比最小值更小的数值。当 `if` 语句执行时，`smallNumber` 的值为 `-Infinity`，所以在继续之前，`smallNumber` 被设置为一个更易于管理的值。


```js
let smallNumber = -Number.MAX\_VALUE \* 2;

if (smallNumber === Number.NEGATIVE\_INFINITY) {
  smallNumber = returnFinite();
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-number.negative\_infinity |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Number.POSITIVE_INFINITY`
* `Number.isFinite()`
* `Infinity`
* `isFinite()`
Function.displayName
====================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

`Function` 实例的 **`displayName`** 可选属性指定函数的显示名称。

值
-

`displayName` 属性最初在任何函数上都不存在，它是由代码作者添加的。出于显示的目的，它应该是一个字符串。

描述
--

如果存在 `displayName` 属性，其可能会被控制台和性能分析工具优先选择，作为函数的名称显示。

在各种浏览器中，只有 Firefox 控制台使用该属性。React 开发者工具在显示组件树时也使用 `displayName` 属性。

Firefox 对可能由匿名 JavaScript 函数命名约定算法生成的 `displayName` 进行了一些基本的解码尝试。以下模式可以被检测到：

* 如果 `displayName` 以一系列字母数字字符、`_` 和 `$` 结尾，最长的这种后缀将被显示。
* 如果 `displayName` 以一系列以 `[]` 包围的字符结尾，该序列将被显示，但不包括方括号。
* 如果 `displayName` 以一系列字母数字字符和 `_`，后面跟着一些 `/`、`.` 或 `<` 结尾，将返回该序列，但不包括尾部的 `/`、`.` 或 `<` 字符。
* 如果 `displayName` 以一系列字母数字字符和 `_`，后面跟着 `(^)` 结尾，该序列将被显示，但不包括 `(^)`。

如果以上模式都不匹配，则显示整个 `displayName`。

示例
--

### 设置 displayName

通过在 Firefox 控制台中输入以下内容，它应该显示为类似 `function MyFunction()` 的内容：


```js
const a = function () {};
a.displayName = "MyFunction";

a; // function MyFunction()
```

### 动态更改 displayName

你可以动态更改函数的 `displayName`：


```js
const object = {
  // anonymous
  someMethod: function someMethod(value) {
    someMethod.displayName = `someMethod (${value})`;
  },
};

console.log(object.someMethod.displayName); // undefined

object.someMethod("123");
console.log(object.someMethod.displayName); // "someMethod (123)"
```

### 清理 displayName

Firefox 开发者工具会在显示 `displayName` 属性之前清理一些常见的模式。


```js
function foo() {}

function testName(name) {
  foo.displayName = name;
  console.log(foo);
}

testName("$foo$"); // function $foo$()
testName("foo bar"); // function bar()
testName("Foo.prototype.add"); // function add()
testName("foo ."); // function foo .()
testName("foo <"); // function foo <()
testName("foo?"); // function foo?()
testName("foo()"); // function foo()()

testName("[...]"); // function ...()
testName("foo<"); // function foo()
testName("foo..."); // function foo()
testName("foo(^)"); // function foo()
```

规范
--

不属于任何规范。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Function.prototype.name`
Function() 构造函数
===============

**`Function()`** 构造函数创建 `Function` 对象。直接调用构造函数可以动态创建函数，但可能会面临一些安全性和类似于 `eval()` 的性能问题（但相对较小）。然而，与具有访问本地作用域的 `eval` 不同，`Function` 构造函数创建的函数仅在全局作用域中执行。

尝试一下
----

语法
--


```js
new Function(functionBody)
new Function(arg0, functionBody)
new Function(arg0, arg1, functionBody)
new Function(arg0, arg1, /\* …, \*/ argN, functionBody)

Function(functionBody)
Function(arg0, functionBody)
Function(arg0, arg1, functionBody)
Function(arg0, arg1, /\* …, \*/ argN, functionBody)
```


**备注：** 调用 `Function()` 时可以使用或不使用 `new`。两者都会创建一个新的 `Function` 实例。

### 参数

`argN` 可选

被函数用作形参的名称。每个名称都必须是字符串，对应于一个有效的 JavaScript 参数（任何一个普通的标识符、剩余参数或解构参数，可选择使用默认参数），或用逗号分隔的此类字符串的列表。

由于参数的解析方式与函数表达式的解析方式相同，所以接受空白和注释。例如：`"x", "theValue = 42", "[a, b] /* numbers */"` 或 `"x, theValue = 42, [a, b] /* numbers */"`。（`"x, theValue = 42", "[a, b]"` 也是正确的，虽然有些难以阅读。）

`functionBody`

一个包含构成函数定义的 JavaScript 语句的字符串。

描述
--

使用 `Function` 构造函数创建的 `Function` 对象会在函数创建时完成解析。这比用函数表达式或函数声明创建一个函数并在代码中调用它的效率要低，因为使用表达式或声明创建的函数会和其他的代码一起被解析。

传递给函数的所有参数，除了最后一个，都被当作要创建的函数中参数的标识符的名称，按照它们被传递的顺序进行处理。该函数将被动态编译为一个函数表达式，其源代码以下列方式组装：


```js
`function anonymous(${args.join(",")}
) {
${functionBody}
}`;
```


这可以通过调用函数的 `toString()` 方法来观察。

然而，与普通的函数表达式不同，`anonymous` 这个名字不会被添加到 `functionBody` 的作用域中，因为 `functionBody` 只能访问全局作用域。如果 `functionBody` 不在严格模式中（主体本身需要有 `"use strict"` 指令，因为它不从上下文中继承严格性），你可以使用 `arguments.callee` 来指代函数本身。另外，你可以将递归部分定义为一个内部函数：


```js
const recursiveFn = new Function(
  "count",
  `
(function recursiveFn(count) {
 if (count < 0) {
 return;
 }
 console.log(count);
 recursiveFn(count - 1);
})(count);
`,
);
```


请注意，集合源的两个动态部分——参数列表 `args.join(",")` 和 `functionBody` 将首先被分别解析，以确保它们在语法上都是有效的。这可以防止类似注入的尝试。


```js
new Function("/\*", "\*/) {");
// SyntaxError: Unexpected end of arg string
// 不会变成 "function anonymous(/\*) {\*/) {}"
```

示例
--

### 与 Function 构造函数一同指定参数

以下代码创建了一个接受两个参数的 `Function` 对象。


```js
// 此示例可在你的 JavaScript 控制台下运行

// 创建一个接受两个参数的函数，并返回这些参数的和
const adder = new Function("a", "b", "return a + b");

// 调用函数
adder(2, 6);
// 8
```


参数 `a` 和 `b` 是在函数体 `return a + b` 中使用的正式参数名称。

### 从函数声明或函数表达式创建一个函数对象


```js
// 函数构造器可以接受多个分号分隔的语句。Function 表达式需要带有函数的返回语句

// 观察一下，new Function 被调用了。这样我们就可以在事后直接调用我们创建的函数了
const sumOfArray = new Function(
  "const sumArray = (arr) => arr.reduce((previousValue, currentValue) => previousValue + currentValue); return sumArray",
)();

// 调用函数
sumOfArray([1, 2, 3, 4]);
// 10

// 如果你不在创建函数时调用 new Function，你可以使用 Function.call() 方法来调用它
const findLargestNumber = new Function(
  "function findLargestNumber (arr) { return Math.max(...arr) }; return findLargestNumber",
);
// 调用函数
findLargestNumber.call({}).call({}, [2, 4, 1, 8, 5]);
// 8

// 函数声明不需要返回语句
const sayHello = new Function(
  "return function (name) { return `Hello, ${name}` }",
)();

// 调用函数
sayHello("world");
// Hello, world
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-constructor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 函数声明
* 函数表达式
* 函数
Function.prototype.call()
=========================

`Function` 实例的 **`call()`** 方法会以给定的 `this` 值和逐个提供的参数调用该函数。

尝试一下
----

语法
--


```js
call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, arg2, /\* …, \*/ argN)
```

### 参数

`thisArg`

在调用 `func` 时要使用的 `this` 值。如果函数不在严格模式下，`null` 和 `undefined` 将被替换为全局对象，并且原始值将被转换为对象。

`arg1, …, argN` 可选

函数的参数。

返回值
---

使用指定的 `this` 值和参数调用函数后的结果。

描述
--

**备注：** 这个函数几乎与 `apply()` 相同，只是函数的参数以列表的形式逐个传递给 `call()`，而在 `apply()` 中它们被组合在一个对象中，通常是一个数组——例如，`func.call(this, "eat", "bananas")` 与 `func.apply(this, ["eat", "bananas"])`。

通常，在调用函数时，函数内部的 `this` 值是访问该函数的对象。使用 `call()`，你可以在调用现有函数时将任意值分配给 `this`，而无需首先将函数附加到对象上作为属性。这样可以将一个对象的方法用作通用的实用函数。

**警告：** 不要使用 `call()` 来链式调用构造函数（例如，实现继承）。这会将构造函数作为普通函数调用，这意味着 `new.target` 的值为 `undefined`，而类会抛出错误，因为它们不能在没有 `new` 的情况下被调用。请改用 `Reflect.construct()` 或 `extends`。

示例
--

### 使用 call() 调用函数并指定 this 值

在下面的示例中，当我们调用 `greet` 时，`this` 的值将绑定到对象 `obj`，即使 `greet` 不是 `obj` 的方法。


```js
function greet() {
  console.log(this.animal, "的睡眠时间一般在", this.sleepDuration, "之间");
}

const obj = {
  animal: "猫",
  sleepDuration: "12 到 16 小时",
};

greet.call(obj); // 猫 的睡眠时间一般在 12 到 16 小时 之间
```

### 使用 call() 在不指定第一个参数的情况下调用函数

如果省略第一个 `thisArg` 参数，则默认为 `undefined`。在非严格模式下，`this` 值将被替换为 `globalThis`（类似于全局对象）。


```js
globalThis.globProp = "Wisen";

function display() {
  console.log(`globProp 的值是 ${this.globProp}`);
}

display.call(); // 输出“globProp 的值是 Wisen”
```


在严格模式下，`this` 的值不会被替换，因此它保持为 `undefined`。


```js
"use strict";

globalThis.globProp = "Wisen";

function display() {
  console.log(`globProp 的值时 ${this.globProp}`);
}

display.call(); // 抛出 TypeError: Cannot read the property of 'globProp' of undefined
```

### 将方法转换为实用函数

`call()` 几乎等同于普通函数调用，只是将 `this` 作为普通参数传入，而不是作为函数所在的对象值。这类似于通用的实用函数的工作方式：你可以使用 `map(array, callback)` 来代替 `array.map(callback)`，这样可以避免对 `Array.prototype` 进行修改，还可以将 `map` 用于不是数组的类数组对象（例如 `arguments`）。

以 `Array.prototype.slice()` 为例，你想要将类数组对象转换为真正的数组。你可以创建一个类似这样的快捷方式：


```js
const slice = Array.prototype.slice;

// ...

slice.call(arguments);
```


请注意，你不能将 `slice.call` 保存并将其作为普通函数调用，因为 `call()` 方法也会读取它的 `this` 值，而这个值应该是它要调用的函数。在这种情况下，你可以使用 `bind()` 来绑定 `call()` 的 `this` 值。在下面的代码片段中，`slice()` 是一个绑定了 `this` 值为 `Array.prototype.slice()` 的 `Function.prototype.call()` 的版本。这意味着额外的 `call()` 调用可以被省略：


```js
// 与前面示例中的“slice”相同
const unboundSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(unboundSlice);

// ...

slice(arguments);
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-function.prototype.call |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Function.prototype.bind()`
* `Function.prototype.apply()`
* `Reflect.apply()`
* 展开语法
* JavaScript 对象入门
Function.prototype.arguments
============================

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**备注：** `Function` 对象的 `arguments` 属性已被弃用。访问 `arguments` 对象的推荐方式是在函数内部引用可用的 `arguments` 变量。

`Function` 实例的 **`arguments`** 访问器属性返回传递给该函数的参数。对于严格模式、箭头函数、异步函数和生成器函数，访问 `arguments` 属性会抛出 `TypeError`。

描述
--

`arguments` 的值是一个类数组对象，对应于传入函数的参数。

在递归的情况下，即如果函数 `f` 在调用栈上出现多次，`f.arguments` 的值表示最近一次调用该函数时的参数。

如果函数没有正在进行的、未完成的调用（即函数已被调用但尚未返回），`arguments` 属性的值通常为 `null`。

请注意，ECMAScript 规范只规定了 `Function.prototype` 具有一个初始的 `arguments` 访问器，对于任何 `get` 或 `set` 请求都无条件地抛出 `TypeError`（称为“毒丸访问器”），而且引擎实现不允许改变此语义，除非是非严格的普通函数。（对于非严格的普通函数）`arguments` 属性的实际行为如果不是抛出错误，则该行为由实现定义。例如，Chrome 将其定义为自有的数据属性，而 Firefox 和 Safari 扩展了初始的毒丸访问器 `Function.prototype.arguments`，以特殊处理非严格函数的 `this` 值。


```js
(function f() {
  if (Object.hasOwn(f, "arguments")) {
    console.log(
      "arguments 是带有描述符的自有属性",
      Object.getOwnPropertyDescriptor(f, "arguments"),
    );
  } else {
    console.log(
      "f 没有自有的名为 arguments 的属性。尝试获取 f.[[Prototype]].arguments",
    );
    console.log(
      Object.getOwnPropertyDescriptor(
        Object.getPrototypeOf(f),
        "arguments",
      ).get.call(f),
    );
  }
})();

// 在 Chrome 中：
// arguments 是带有描述符的自有属性 {value: Arguments(0), writable: false, enumerable: false, configurable: false}

// 在 Firefox 中：
// f 没有自有的名为 arguments 的属性。尝试获取 f.[[Prototype]].arguments
// Arguments { … }
```

示例
--

### 使用 arguments 属性


```js
function f(n) {
  g(n - 1);
}

function g(n) {
  console.log(`之前：${g.arguments[0]}`);
  if (n > 0) {
    f(n);
  }
  console.log(`之后：${g.arguments[0]}`);
}

f(2);

console.log(`返回：${g.arguments}`);

// 输出：
// 之前：1
// 之前：0
// 之后：0
// 之后：1
// 返回：null
```

规范
--

不属于任何规范。

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `arguments`
* 函数
Function.prototype.toString()
=============================

`Function` 实例的 **`toString()`** 方法返回一个表示该函数源码的字符串。

尝试一下
----

语法
--


```js
toString()
```

### 参数

无。

### 返回值

一个表示函数源代码的字符串。

描述
--

`Function` 对象重写了从 `Object` 继承来的 `toString()` 方法，而没有继承 `toString`。对于用户定义的 `Function` 对象，`toString` 方法返回一个字符串，其中包含用于定义函数的源文本段。

当 `Function` 需要表示为文本值时，JavaScript 会自动调用函数的 `toString` 方法，例如：函数与一个字符串进行拼接。

若 `this` 不是 `Function` 对象，则 `toString()` 方法将抛出 `TypeError` 异常（"Function.prototype.toString called on incompatible object"）。


```js
Function.prototype.toString.call("foo"); // 抛出 TypeError
```


如果在内置函数对象上调用 `toString()` 方法，或者在由 `Function.prototype.bind()` 创建的函数以及在其他非 JavaScript 函数上调用 `toString()`，那么 `toString()` 将返回一个看起来*像原函数的字符串*，类似于：
```

function someName() { [native code] }
```


对于内部对象方法和函数，`someName` 是函数的初始名称；否则其可能是实现定义（implementation-defined）的，但始终以属性名称语法的形式呈现，如：`[1 + 1]`、`someName` 或 `1`。

**备注：** 这意味着对原生函数的字符串调用 `eval()` 将始终产生语法错误。

若是在由 `Function` 构造函数生成的函数上调用 `toString()`，则 `toString()` 返回创建后的函数源码，包括形参和函数体，函数名为“anonymous”。例如：对于 `Function("a", "b", "return a + b").toString()`，则会返回：
```

function anonymous(a,b
) {
return a + b
}
```


从 ES2018 开始，规范要求 `toString()` 的返回值与声明的源代码完全相同，包括空格和注释；或者因某种原因，主机没有源代码，则要求返回一个原生函数字符串。参见兼容性表格以查询对这一修改后的行为的支持情况。

示例
--

### 比较实际源代码与 toString 的结果


```js
function test(fn) {
  console.log(fn.toString());
}

function f() {}
class A {
  a() {}
}
function\* g() {}

test(f); // "function f() {}"
test(A); // "class A { a() {} }"
test(g); // "function\* g() {}"
test((a) => a); // "(a) => a"
test({ a() {} }.a); // "a() {}"
test({ \*a() {} }.a); // "\*a() {}"
test({ [0]() {} }[0]); // "[0]() {}"
test(Object.getOwnPropertyDescriptor({ get a() {} }, "a").get); // "get a() {}"
test(Object.getOwnPropertyDescriptor({ set a(x) {} }, "a").set); // "set a(x) {}"
test(Function.prototype.toString); // "function toString() { [native code] }"
test(function f() {}.bind(0)); // "function () { [native code] }"
test(Function("a", "b")); // function anonymous(a\n) {\nb\n}
```


注意：在 `Function.prototype.toString()` 的行为变更后，在调用 `toString()` 时，不允许对该方法的实现在其不是原生函数的字符串时合成函数的源码。方法始终返回创建函数时使用的确切的源代码——包括以上示例中的 getter 和 setter。`Function` 构造函数本身具有合成函数源代码的能力（即，一种隐式的 `eval()` 形式）。

### 获取函数的源文本

可以通过将函数强制转换为字符串来获取函数的源文本——例如，通过将其包装在模板字符串中：


```js
function foo() {
  return "bar";
}
console.log(`${foo}`);
// function foo() {
// return "bar";
// }
```


得到的源文本是*准确的*，包括其中的注释（否则引擎的内部表示不会存储这些注释）。


```js
function foo /\* a comment \*/() {
  return "bar";
}
console.log(foo.toString());
// function foo /\* a comment \*/() {
// return "bar";
// }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-function.prototype.tostring |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.prototype.toString()`