浏览器DevTool自带了一个Console。这个Console实现了一个javascript的repl。一直好奇过这东西是怎么实现的————页面上的js还在跑,它怎么插一条语句进来?
其实很简单,首先想一想,如果现在要在一个普通js运行时里面实现一个控制台,自己会如何实现?
当然是通过现有的消息循环了。从控制台读一条语句和从网络拉一条数据又有什么区别呢?
实验
通过一组实验来验证一下这个猜想:构造一个死循环,让js无法回到消息循环里面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
console.log("entering dead loop...")
while (1) { }
</script>
</body>
</html>
|
打开这个页面,发现连F12都打不开了……
微调一下,给我们一个打开DevTool的机会:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
setTimeout(() => {
console.log("entering dead loop...")
while (1) { }
}, 1000);
</script>
</body>
</html>
|
现在F12能打开。输入一条语句后,会发现回车按不下去,自动补全功能也没了:

结论
往DevTool里的Console插一条语句,其实就相当于往消息循环里插了一条eval()
。