Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么与document.write一起插入的脚本可以写入更改变量_Javascript - Fatal编程技术网

Javascript 为什么与document.write一起插入的脚本可以写入更改变量

Javascript 为什么与document.write一起插入的脚本可以写入更改变量,javascript,Javascript,为什么下面的脚本打印的是33而不是31 <script> var i = 1; document.write("<script> i=3; document.write(i); </scr" + "ipt>"); document.write(i); </script> var i=1; document.write(“i=3;document.write(i);”; 文件.编写(i); 这张打印31,有什么区别 <script>

为什么下面的脚本打印的是33而不是31

<script>
var i = 1;
document.write("<script> i=3; document.write(i); </scr" + "ipt>");
document.write(i);
</script>

var i=1;
document.write(“i=3;document.write(i);”;
文件.编写(i);
这张打印31,有什么区别

<script>
var i = 1;
document.write("<script> i=3; document.write(i); </scr" + "ipt>" + i);
</script>

var i=1;
document.write(“i=3;document.write(i);”+i);

这是它的工作顺序:

  • 定义一个名为
    i
    的变量,其值为
    1
  • 向文档中写入新脚本

    2.1。这个新脚本将
    i
    重新定义为
    3

    2.2。脚本将
    i
    (请记住,现在
    3
    )写入文档

  • 再次将
    i
    写入文档(该值与重新定义时的值相同,
    3

  • 最终结果是
    33
    ,因为您写了两次
    3

  • 这是第二个块的顺序:

  • 使用值
    1
    定义变量
    i
  • JavaScript连接字符串和
    i
    ,创建
    “i=3;document.write(i);1”
    (注意末尾的
    1
    ,这就是连接)
  • JavaScript将新的连接字符串写入文档

    3.1<代码>i被重新定义为
    3

    3.2<代码>文档。编写的
    i
    (以前重新定义为
    3

  • 由于连接和
    document.write
    ,最终您的文档是
    “3i=3;document.write(i);1”
    。显然,
    的内容是不可见的。因此,您将得到
    31


  • 这是它工作的顺序:

  • 定义一个名为
    i
    的变量,其值为
    1
  • 向文档中写入新脚本

    2.1。这个新脚本将
    i
    重新定义为
    3

    2.2。脚本将
    i
    (请记住,现在
    3
    )写入文档

  • 再次将
    i
    写入文档(该值与重新定义时的值相同,
    3

  • 最终结果是
    33
    ,因为您写了两次
    3

  • 这是第二个块的顺序:

  • 使用值
    1
    定义变量
    i
  • JavaScript连接字符串和
    i
    ,创建
    “i=3;document.write(i);1”
    (注意末尾的
    1
    ,这就是连接)
  • JavaScript将新的连接字符串写入文档

    3.1<代码>i被重新定义为
    3

    3.2<代码>文档。编写的
    i
    (以前重新定义为
    3

  • 由于连接和
    document.write
    ,最终您的文档是
    “3i=3;document.write(i);1”
    。显然,
    的内容是不可见的。因此,您将得到
    31


  • 为了使第一个示例的输出为31,在解析器对输出执行任何操作之前,最外层的脚本块必须一直运行,生成其所有输出。这是一种完全合理的方式来认为它会起作用(我认为它多年来一直如此);这是不对的。:-)浏览器比这更主动

    浏览器的解析器和JavaScript引擎必须协同工作来处理不使用
    async
    defer
    属性的脚本标记。这其中有两个关键点:

  • 当解析器看到一个完整的
    脚本
    块时,它尖叫着停止,并将其交给JavaScript引擎立即运行

  • 调用
    document.write
    向解析器提供新标记;如果解析器看到一个完整的标记,它将在调用
    document.write时处理它。如果完整的令牌是一个脚本块,“处理它”涉及在当前调用JavaScript引擎期间再次调用它。您可以将每个
    文档看作是对解析器的调用,将每个完整的脚本块看作是对JavaScript引擎的调用。与函数调用一样,这些调用也可以嵌套

  • 第二点就是为什么你看到的是33而不是31。使用
    文档编写的脚本。write
    在调用
    文档的过程中执行。write
    ,而不是在之后执行,因此
    i
    文档完成之前更新为
    3
    (并输出)。write
    完成。因此,当您到达
    文档。在主脚本块的末尾写入
    时,
    i
    已更改为
    3
    ,并已输出一次

    在第二个示例中,在调用
    文档之前使用
    i

    这可能会使通话顺序更加清晰:

    <script>
    document.write("<script>document.write('a');</scr" + "ipt>");
    document.write('b');
    </script>
    
    
    document.write(“document.write('a');”);
    文件。写('b');
    

    结果是
    ab
    ,而不是
    ba
    。第一个
    文档的代码输出。write
    在最后一个
    文档之前运行。write
    运行,因此中间
    文档的输出。write
    显示在最后一个文档的输出之前。

    为了使第一个示例的输出为31,在解析器对输出执行任何操作之前,最外层的脚本块必须一直运行,生成其所有输出。这是一种完全合理的方式来认为它会起作用(我认为它多年来一直如此);这是不对的。:-)浏览器比这更主动

    浏览器的解析器和JavaScript引擎必须协同工作来处理不使用<代码的脚本标记