ToPrimitive VS OrdinaryToPrimitive

问题描述 投票:0回答:1

我正在读凯尔·辛普森 (Kyle Simpson) 写的《YDKJS》一书,主题是“强制”。在查看 specs 时,我发现 ToPrimitive 有条件地调用 OrdinaryToPrimitive。我在博客中读到:

使用 [Symbol.ToPrimitive] 方法将 JavaScript 视图对象视为奇异的,并且定义了奇异的ToPrim 属性

这意味着如果对象的exoticToPrim属性未定义,则调用OrdinaryToPrimitive。

示例:

 1. var a = 42;    
 2. a + " "; 
 3. String(a);

我的查询(强制如何在幕后运作):

  1. 为了串联,原始值“a”将在某处被装箱到动态 Number 对象?
  2. 第 2 行中传递的提示将是默认值(即数字),但在第 3 行中,它将是字符串。仅在显式转换时传递提示?
  3. 强制转换期间会调用 OrdinaryToPrimitive 吗?由于 Number.prototype 不包含方法,Symbol.toPrimitive (因为 Reflect.ownKeys(Array.prototype) 不返回 Symbol.toPrimitive),因此 exoticToPrim 将是未定义的。即使对于其他对象(例如 Array.prototype 不包含此方法),根据 spec 7.1.1 ,1a 和 1b 也仅针对 custom 外来对象(覆盖 Symbol.prototype 的对象)执行。原始)。

注意:我知道抽象操作是什么,并且引擎自行定义它们,并且我们不能显式调用它们(尽管覆盖它们)

javascript language-lawyer coercion
1个回答
0
投票

为了串联,原始值“a”将在某处被装箱到动态 Number 对象?

不。您错过了

[Symbol.toPrimitive]
属性仅适用于 objects。您可以看到ToPrimitive所做的第一个操作是检查“If
input
是一个Object
”。

所以这根本不适用。没有拳击发生,也没有调用任何方法。原始值

42
立即从 ToPrimitive 返回。然后将其传递给 ToString 操作,因为
+
的另一个操作数是字符串。

仅在显式转换时传递提示?

您可以轻松检查所有调用 ToPrimtive 的地方的规范。一般来说,会传递一个提示,我发现唯一没有传递提示的地方是

+
运算符、将对象与原始值进行比较时的
==
/
!=
运算符,以及调用
new Date
时的奇怪情况有一个参数(不是
Date
对象)。

强制过程中会调用

OrdinaryToPrimitive
吗?

不。使用

String()
函数 的强制转换直接调用(符号除外)ToString 操作,该操作同样不会在非对象上使用 ToPrimitive (或 OrdinaryToPrimitive)。相反,对于数字,它直接分派到数字到字符串操作

© www.soinside.com 2019 - 2024. All rights reserved.