<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="text/javascript">
var src=document.querySelector("script");
document.body.removeChild(src);
alert(1);
</script>
</body>
</html>
如上代码,dom中已经没了这个script标签 ,为什么下面代码alert(1)
还在执行?
楼主这个题目提得非常好,我刚花了一段时间google一下才搞懂,之前还误会了楼主的意思真是抱歉。
原因其实也就是js的按块执行、非阻塞I/O以及Event loop机制。JavaScript代码块被执行,创造出自己的执行环境后,就完全和dom中的script
标签脱离了。事件队列中的事件全都执行完毕后执行环境才被销毁。
Removed JavaScript is still executable
The JavaScript Event Loop: Explained
Concurrency model and Event Loop
代码已经在列队中了,所以删除了还是会执行完
我在JavaScript高级程序设计那本书上看到这个知识点,在删除带有事件处理程序或引用了其他JavaScript对象子树时,就有可能导致内存占用问题。假设某个元素有一个事件处理程序(或者引用了一个JavaScript对象作为属性),在使用前述某个属性将该元素从文档树中删除后,元素与事件处理程序(或JavaScript对象)之间的绑定关系在内存中并没有一并删除。如果频繁出现这种情况,页面占用的内存数也会明显增加。
细节需要深入到浏览器的处理机制才可以。
不过我猜测是在处理js的时候会有个预处理的过程,在这个过程已经知道要运行的js了,也许这个script已经存在了某个地方,你删掉了script只是对dom影响,也没有用。
<script type="text/javascript">
var src=document.querySelector("script");
document.body.removeChild(src);
function a(){
alert(1);
}
a();
</script>
换一种写法,可以看到方法a()已经被浏览器解析了,所以就会执行了。
會不會是你已經運行過正確的,然後緩存了
JavaScript解释器在执行脚本时,是按块来执行的,简单来说,浏览器在解析HTML文档流时,如果遇到一个script标签时,javascript解释器会等待这个代码块都加载完了,才进行预编译,然后才执行。
所以,当开始执行这个代码块的代码时,这个代码段已经被解析完了。这时再从DOM中删去也就不影响代码的执行了。