在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?
请每个回答只回答一个特征。
当前回答
在JavaScript中,void不是关键字,不是类型声明,也不是变量名,也不是函数,也不是对象。Void是一个前缀操作符,类似于-、——、++和!你可以给任何表达式加上前缀,这个表达式的值将是undefined。
它经常被用在bookmarklet和内联事件处理程序中,比如下面这个比较常见的例子:
<a href="javascript:void(0)">do nothing</a>
在这个例子中使用它的方式使它看起来像一个函数调用,而实际上它只是一种获得原始未定义值的过于聪明的方法。大多数人并没有真正理解JavaScript中void的真正本质,这可能会导致许多讨厌的bug和奇怪的意想不到的事情发生。
不幸的是,我认为void操作符是在JavaScript中获得未定义值的唯一真正保证的方法,因为未定义,正如在另一个回答中指出的,是一个可以重新赋值的变量名,而{}。a可以被Object.prototype.a = 'foo'打乱
更新:我想到了另一种生成undefined的方法:
(function(){}())
嗯,有点啰嗦,返回“undefined”是它的目的就更不清楚了。
其他回答
很久以前,我曾经用BUT子句构建过一种语言。
Java的Integer类的基转换静态方法。P似乎很少有语言内置了这个功能。
PHP作为一门完整的语言基本上是WTF。
语言定义(参见www.php.org)不是由语法或标准定义的,而是由一堆“你可以写这个例子”的部分(当然,你可以写其他东西,只是猜测泛化)定义的,诚实的用户说“但它做了这种古怪的事情……”。
在使用我们构建的PHP解析器时,我经常会遇到一些故障。这是最新的消息:
"abc$A[define]def"
现在,PHP是PERL的一个(非常糟糕的)副本,因此它允许用隐式变量替换构造字符串。字符串中的$X表示“将$X的值插入字符串”,相当于“abc”。$ X。"def",其中"."是PHP的字符串连接操作符。
字符串中的$A[7]表示“将数组$A的第七个槽的值插入字符串”,相当于“abc”。美元[7]。“def”。
现在,语言(网站)清楚地说“定义”是一个关键字,你不能 只要你能找到合适的表达就用它。那么上面包含“define”的宝石做什么呢?抛出语法错误?不,那样说得通。
不,它实际上的意思是:
"abc" . $A["define"] . "def"
只有当你在一个字符串的简单数组访问中写一个看起来像标识符(关键字或不是!)的东西时,它才会这样做。在语言的其他地方没有这种行为。 什么,写“abc$A["define"]def”是不合理的,所以PHP发明者不得不把它扔进去?得了吧。(更严重的是,“字符串中有复杂的数组访问”,当然它的工作方式不同。查看"abc{$A[define]}def";根据PHP网站,这是非法的。
(PHP数组是关联哈希表,因此根据名称查找数组(嗯,哈希表)成员并不是一个糟糕的想法)。
语言中充满了这样的陷阱。如果你喜欢“天哪,看看我今天在子程序下发现了什么蠕动的东西”,你应该切换到PHP。
在ColdFusion中,数组从1开始。
Forth的控制结构有些奇怪。首先,因为它是一种反向波兰符号语言,条件在IF之前,如:
x 0 = IF
现在,要关闭条件块,使用关键字THEN:
x 0 = IF ." Equals zero!" THEN
现在真正的WTF开始了。IF所做的是编译一个有条件的前向跳转,并将跳转偏移量的地址放在堆栈上。当找到THEN时,它从堆栈中弹出该地址,计算实际偏移量,然后编译它。另一方面,ELSE编译一个条件向前跳转,从堆栈中弹出一个地址,将一个新地址压入堆栈,计算弹出地址的偏移量,然后编译该偏移量。这意味着语法是这样的:
x 0 = IF ." Equals zero!" ELSE ." Not equal to zero!" THEN
第一个和第二个语句是这样编译的:
x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ)
x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ) BRANCH LITERAL offset SLITERAL" Not equal to zero!" (DOTQ)
更奇怪的是,这种行为并不隐藏。它是该语言的ANSI规范的一部分,可以通过构造自定义流控制结构或以有趣的方式组合它们来自由利用。例如,Forth的WHILE循环:
BEGIN x 10 < WHILE x 1+ to x REPEAT
BEGIN和WHILE之间的部分是任意代码,因此实际上可以在单个控制结构中让代码在条件测试之前和之后执行。这是故意的,但下面的内容虽然是允许的,但却不允许:
BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN
它利用了每个控制流字的工作方式来组合两个WHILE语句,并为每个出口添加不同的后循环代码来引导。为了表明我不是在开玩笑,我只是从互联网上的一个代码中复制了这个小片段,并进行了一些小的修改来简化它。