0

好的,我一直在做一些研究,并在测试对象类型或更恰当的时候开始使用这个约定,检测 typeof ..

 ({function:1}[typeof somefunc])

这行得通,但是唉 - 我在 IE 中测试过,错误。所以,不再使用它.. :-) ,.. 但是。

所以,我恢复到以标准方式进行测试,没什么大不了的(typeof somefunc === "function" 或 $.isFunction(somefunc))。但我很好奇“为什么”它在 IE 中不起作用。

另外,有人可以解释为什么这个“确实”在 Firefox 中有效,或者我的意思是这个表达对我来说很奇怪,我想知道它为什么有效的内部原理(即使在选择性浏览器中)。我不明白它如何反向引用函数:1 作为 typeof 的测试?

4

3 回答 3

3

{function:1}是一个对象,只有一个键,'function',映射到一个真值,1。所以,({function:1}['function'])是真的,但(例如)({function:1}['string'])是假的。

最有可能的是,IE 不支持它的原因是它function是一个保留字(您必须知道),而 IE 显然被它在这种情况下的使用弄糊涂了。(如果是这样,这是 IE 中的一个错误:令人惊讶的是,规范实际上确实允许在这种情况下使用保留字。)

于 2013-10-25T06:53:53.880 回答
3

IE8 和更早版本中的 JScript 解析器遵循旧的 ECMAScript 3.1 (1999) 对象初始值设定项规则,该规则要求如果您想使用保留字(如function)作为属性名称,它必须用引号引起来。从 ECMAScript5 (2009) 开始,不再需要引号,因为上下文是明确的。自规范更新 (IE9+) 以来发布的 IE 版本确实允许您省略引号。

不同之处在于,在 ECMAscript5 中,对象初始化语法中的PropertyName只是IdentifierName,而不是IdentifierIdentifier是不是ReservedWord的IdentifierName。是有效的IdentifierName,但不是有效的Identifier因为它是ReservedWord。更多:标识符名称标识符。但是旧的规范并没有区分IdentifierNameIdentifier,所以要在那里使用,你必须把它放在引号中。functionfunction(感谢chuckj提醒我这在ECMAScript5 中发生了变化。)

另外,有人可以解释为什么这个“确实”在 Firefox 中有效,或者我的意思是这个表达对我来说很奇怪......

是的,这很奇怪,任何使用它编写代码的人都可能会偶然发现它。这是一种简短的写作方式(typeof somefunc=="function")。这是正在发生的事情:

  1. 该表达式创建一个具有一个属性的对象,在这种情况下,属性名称为function,值为1

  2. typeof somefunc部分"function"针对 JavaScript 函数、"object"各种对象、"number"数字原语、"string"字符串原语等进行评估并返回。

  3. 该属性名称用于在步骤 1 中创建的对象上查找属性。如果找到该属性,则表达式的总体结果是1,一个真值。如果未找到该属性,则总体结果为undefined,一个虚假值。

所以({function:1}[typeof somefunc])测试是否typeof返回"function". 同样,somefunc您可以({object:1}[typeof someobj])检查是否typeof返回"object"someobj({string:1}[typeof somestring])检查是否typeof返回"string"somestring


旁注:与直截了当的测试相比,这种晦涩难懂的测试方式根本(typeof somefunc=="function")表现不佳:测试为真| 测试为假不足为奇,因为它typeof x == y可以通过一个好的优化引擎进行高度优化。所以这种检查方式更难阅读,更长,更不容易打字,而且通常更慢。嗯.... :-)

于 2013-10-25T06:58:54.383 回答
2

只是把function引号作为function保留关键字,但"function"只是一个字符串文字

({"function":1}[typeof somefunc])

应该可以正常工作

但是,你为什么不简单地使用:

(typeof somefunc == "function")

它更短更直观

于 2013-10-25T06:58:27.467 回答