好的,我一直在做一些研究,并在测试对象类型或更合适的时候开始使用这个约定,检测类型..
({function:1}[typeof somefunc])
这是有效的,但唉 - 我在IE中测试过,错误。所以,不再使用它.. :-),..但是。
所以,我恢复了以标准方式测试,没有biggie(typeof somefunc ===“function”或$ .isFunction(somefunc))。但我很好奇“为什么”它在IE中不起作用。
此外,有人可以解释为什么这个“确实”在Firefox中工作,或者我的意思是说这个表达对我来说很奇怪,我想知道它为什么有效的内部结构(即使在选择性浏览器中)。我不明白它的反向引用功能如何:1作为带有typeof的测试?
答案 0 :(得分:3)
{function:1}
是一个对象,只有一个键'function'
,映射到真值1
。因此,({function:1}['function'])
是真实的,但(例如)({function:1}['string'])
是假的。
最有可能的是,IE不支持它的原因是function
是一个保留字(正如你必须知道的那样),而且显然IE在这种情况下的使用感到困惑。 (如果是这样,这在IE中是一个错误:令人惊讶的是,规范实际上允许在这种情况下使用保留字。)
答案 1 :(得分:3)
IE8及更早版本中的JScript解析器遵循旧的ECMAScript 3.1(1999)对象初始化器规则,这些规则要求如果要使用保留字(如function
)作为属性名称,则必须使用在引号中。从ECMAScript5(2009)开始,不再需要引号,因为上下文是明确的。自规范更新后发布的IE版本(IE9 +)确实允许你不用引号。
不同之处在于,在ECMAscript5中,the object initializer grammar中的 PropertyName 只是 IdentifierName ,而不是 Identifier 。 标识符是 IdentifierName ,它不是 ReservedWord 。 function
是有效的 IdentifierName ,但不是有效的标识符,因为它是 ReservedWord 。更多:Identifier Names and Identifiers。但旧的规范没有区分 IdentifierName 和 Identifier ,因此要在那里使用function
,你必须把它放在引号中。 (感谢chuckj提醒我ECMAScript5中的更改。)
此外,有人可以解释为什么这个“确实”在Firefox中有效,或者我的意思是说这个表达对我来说很奇怪......
是的,这很奇怪,任何使用它的代码工作的人都可能偶然发现它。这是写(typeof somefunc=="function")
的简短方法。这是正在发生的事情:
表达式创建一个具有一个属性的对象,在这种情况下,属性名称为function
,值为1
。
评估typeof somefunc
部分,并为JavaScript函数返回"function"
,为各种对象返回"object"
,为数字原始"number"
返回"string"
{1}}用于字符串原语等
该属性名称用于在步骤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")
相比,这种模糊的测试方式在 时表现不佳:Test when true | Test when false不足为奇,因为typeof x == y
可以通过优秀的优化引擎进行高度优化。因此,这种检查方式更难阅读,更长,更容易打字,而且通常更慢。嗯....: - )
答案 2 :(得分:2)
只需将function
放在引号中,因为function
是保留关键字,但"function"
只是字符串文字
({"function":1}[typeof somefunc])
应该可以正常工作
但是,为什么你不能简单地使用:
(typeof somefunc == "function")
它更短更直观