由void引发的错误
SyntaxError: Unexpected token + SOMETHING
匹配语法错误在js中并不陌生,从它提示的内容中也很容易明白报错的原因。但是浏览器给出的提示的位置并不很准确,实际上发生错误的地方一般是提示的左近。更有甚者根本就无法找到出错的地方,只能一点点排查。void使用错误引发的就是这样的一个错误。
bug始末
今天解决报上来的一个bug:一个<a/>
标记作为提交按钮,其他浏览器都正常,只有ie6报了个语法错误就什么都不做了。源代码形如下:
<form id="formId" action="/somepage.php" target="_self">
...
<a href="javascript:void()"
onclick="$('#formId').submit();">提交</a>
</form>
在测试时发现Chrome的console中也会报错(SyntaxError: Unexpected token )
),然后页面就跳转了,如果不看console表现倒是正常。
Chrome中bug的错乱定位
开始还以为<a/>
或者<form/>
还有其他注册的事件,于是试着注销事件、拦截冒泡,逐层下来才发现只是<a/>
本身的原因。与平常不同也就是href="javascript:void()"
了,平常写的时候是void(0)
的,修改下再运行,还真就好了。原来只是void这个运算符用错了。
在console中试验下:
void
触发错误:SyntaxError: Unexpected token }
void()
触发错误:SyntaxError: Unexpected token )
void 是什么
void在javascript中是一个一元运算符。它总是舍弃运算数的值,返回undefined。
日常很少用到void,通常有两种情景:
- 阻止链接的默认事件:
href="javascript:void(0)"
(这种javascript伪协议阻止默认事件不推荐,更好的方式通过event.preventDefault()
或IE下returnValue = false
) - 获得一个undefined值:
void 0
或void(0)
(undefined并不是保留字,有些浏览器下是可写的)
void 0
和 void(0)
两种写法都是可以的,后者更像一个函数。javascript中一元运算符都可以用这两种方式书写,但是像上面实验触发错误那样只写一个运算符,或者括弧中什么都没有,他们都会触发同样的错误。这样的一元运算符有:
- typeof: 类型判断
- new: 对象创建符(你没用过
new(Object)
吧?:P) - delete: 删除对象的属性、数组元素或变量。浏览器实现和规范有出入,一般只用来删除对象的属性,另外它的返回值也挺有意思,很多时候都是true。
- void: 返回一个真正的undefined
一元运算符后面都可以用括号把表达式括起来,虽然看起来是函数的调用方式,但括号仅仅是括起表达式。
话外
关于undefined,一般比较容易看到的写法如下:
(function (global, undefined) {
// ...
})(this)
这样也能保证在这个自调用函数的作用域空间内,undefined确实是真正的undefined,而不是被定义成了别的值。