javascript:伪协议与void运算符

巩固两个基础小知识:javascript:伪协议与void运算符。

void运算符

void运算符 对给定的表达式进行求值,然后返回undefined

void 0void (0)都是对0这个表达式求值,然后void表达式自身返回值是undefined

利用void运算符可以把函数声明识别为函数表达式并执行:

1
2
3
void function mod() {

}();

这就是IIFE立即调用的函数表达式的另外一种写法。

void 0也可以用来获取undefined这个值的原始值。假如你担心undefined被开发者莫名其妙的改写了的话,那么void 0依然能够返回undefined的原始值。

1
2
3
4
var undefined = '1';
var b;
b === undefined;// false
b === void 0;// true

箭头函数标准中,允许在函数体不使用括号来直接返回值。 如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。安全起见,当函数返回值是一个不会被使用到的时候,应该使用void运算符,来确保返回undefined(如下方示例),这样当API改变时,并不会影响箭头函数的行为。

1
button.onclick = () => void doSomething();

javascript:伪协议

在html中,可以给超链接的href属性设置javascript:伪协议的内容,如:

1
<a href="javascript:alert(1);">

javascript:伪协议的作用是执行javascript:后面的js语句,并在最后一条语句的返回值不是undefined的时候,把该值作为文档内容,在当前页面中替换或者新窗口中打开。 如果伪协议返回的是undefined,则链接不会发生跳转。

利用这个特性,可以在通过伪协议来打开新的空白文档:

demo01.html
1
2
3
4
5
6
7
8
9
10
11
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript:伪协议测试</title>
</head>
<body>
<a href="javascript: '<script>window.opener.makeContent(window)</script>';" target="_blank">测试</a>
<script src="demo01.js"></script>
</body>
</html>

demo01.js
1
2
3
4
5
6
var someContent = 'some content';

function makeContent({document}){
let parentContent = someContent
document.write(`<div>${parentContent}</div>`)
}

上述代码,可以通过伪协议在新窗口中显示指定内容。

demo2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript:伪协议测试</title>
<script>
var foo = 'foo'
function replace() {
return `<a href="javascript:alert(window.foo);">get foo</a>`
}
</script>
</head>
<body>
<a href="javascript: replace();">测试</a>
</body>
</html>

上述代码,可以通过伪协议来替换当前文档的内容,并且在替换之后,通过点击get foo链接,还能看到新文档的window对象已经发生变化,无法再访问到原来文档中的foo变量。

javascript:;vsjavascript: void(0)
二者区别不大。javascript:;更简洁,javascript: void(0)更有代码含义。