【问题标题】:Why does assigning to `NaN` or `undefined` cause a TypeError?为什么分配给 `NaN` 或 `undefined` 会导致 TypeError?
【发布时间】:2016-09-03 08:29:51
【问题描述】:

A.S.:问题是关于错误的类型,而不是关于现象

如果NaNundefined 等系统变量发生更改,"use strict" 将抛出 TypeError。
但是为什么它是 TypeError 呢?为什么不是语法错误?


编辑: 真的,这里不是 SyntaxError,因为 sn-p 的语法没有错误。
但错误的根源在于,某些受保护的对象无法手动更改;所以,这很可能是 Access错误(我知道没有这样的错误)。
那么,为什么访问错误看起来像类型错误?

【问题讨论】:

  • 因为它们(出于所有意图和目的)是全局对象(又名:变量)的属性
  • 它没有被“保护”。它只是只读的。

标签: javascript typeerror


【解决方案1】:

在 ES5 中,有 6 种不同的native errors

  • EvalError

    本规范中当前未使用此异常。这 对象保持与以前版本的兼容性 规范。

  • RangeError

    表示数值已超出允许范围。

  • ReferenceError

    表示检测到无效的参考值。

  • SyntaxError

    表示发生了解析错误。

  • TypeError

    表示操作数的实际类型与预期不同 输入。

  • URIError

    表示在一个全局 URI 处理函数中使用了一个 方式不符合其定义。

在您的情况下,抛出错误是因为您尝试将值分配给 window.NaNwindow.undefined,它们是不可写的属性。

在分配新值之前,内部[[Put]] 方法会检查[[CanPut]],这将返回false,因为该属性是不可枚举的。因此 [[Put]] 会抛出。

所以问题是分配的引用(assignment expression 中的左操作数)的可写性不是预期的。那么,在上面的 6 种错误中,最合适的似乎是 TypeError,即使可写性不完全是 type

【讨论】:

  • 请注意,jsc 在分配给 NaN 时不会引发错误,并且在 1=2 上会出现 ReferenceError:“异常:ReferenceError:分配的左侧不是引用。”由于typeof(NaN)=typeof(1)=number,引用错误可能确实更合适。
  • @MichaelBar-Sinai 不,因为NaN 是一个标识符,它可以是resolvedreference {base: globalObject, referencedName: "NaN", strictFlag: whatever}。那么 ReferenceError 就不合适了。 1 不是标识符,因此无法解析为引用,然后 1=2 会引发 ReferenceError。注意分配给NaNcan potentially succeed,不同于分配给1
  • @Oriol 这只是一个常规变量。这里没什么可看的。
【解决方案2】:

因为NaNundefined 只是window 的只读属性。它们不是运算符(如>+),也不是关键字(如varclass)。

尝试将某些内容分配给 NaN 在 Chrome 中会出现以下错误:

TypeError:无法分配给对象“#<Window>”的只读属性“NaN

【讨论】:

  • @ayushgp 节点给出了类似的错误:“TypeError:无法分配给# 的只读属性'NaN'”。这是因为在 Node 中global 是全局对象,Object 是它的构造函数。
  • @ayushgp:Node 的 V8 JavaScript 引擎不是和 Google Chrome 一样吗?
  • @DmitryParzhitsky 是的,相同的引擎,但不同的环境;出于显而易见的原因,节点没有window
【解决方案3】:

因为这是一个没有意义的有效论点。但它在语义层面没有意义,在句法层面也没有意义。

这是一个例子:

1+1=42

这是错误的,但它的错误方式不同于:

42 1 1 + =

您可以将第一个理解为算术方程(一加一等于四十二)。第二个,你连读都不会。

这里也一样。声明 NaN=300; 可以在 Javascript 中读取为“让 NaN 指向值 300`。但是当解析器将此请求提交给引擎时,引擎会变为“不,不能这样做”。

【讨论】:

  • 感谢您的回答。我扩大了这个问题。
  • 第二个是totally readable,意思和第一个完全一样:-)
  • @Bergi 我正要链接那个!
  • @Bergi 哦,亲爱的。完全错过了。我猜是迈克尔:0 迈克尔的潜意识:1。
【解决方案4】:

语法错误
在大多数编程和脚本语言中,这通常意味着您在错误的地方使用了运算符。
有关“语法错误”的更多信息,请查看这篇文章:https://en.wikipedia.org/wiki/Syntax_error

输入错误
当数据类型与某些要求不匹配时,就会发生这种情况。
有关“数据类型”的更多信息,请查看这篇文章:https://en.wikipedia.org/wiki/Data_type

因此,类型错误被抛出,因为NaNundefined 是“数据类型”,它们是具有特定(指定)值的全局常量,而“严格模式”防止不允许更改这些问题。

【讨论】:

  • NaNundefined 在非严格模式下也不能更改。
  • 这取决于您使用的 JavaScript (ES) 版本以及平台;比如不同的浏览器、NodeJS等。
猜你喜欢
  • 2019-11-15
  • 2012-06-05
  • 2012-11-07
  • 2021-12-12
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2022-12-05
相关资源
最近更新 更多