整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

你可曾见过如此简单粗暴的JavaScript解说-js脚本运行机制

先,上几道我编写的 js 题,作为分析的样本。

请根据代码,选择正确的选项。

第一题

var a = 0;
function test(){
 alert(a);
}
test();

A. 0

B. null

C. undefined

第二题

var a = 0;
function test(){
 alert(a);
 a = 100;
}
test();

A. 0

B. null

C. undefined

第三题

var a = 0;
function test(){
 alert(a);
 var a = 100;
}
test();

A. 0

B. 100

C. undefined

正确答案:

A , A , C

前两题没啥好说的,之前关于闭包的博文中已经讲得很清楚了,函数 test 形成了自己的闭包,所以能够访问到全局作用域里面的变量 a 。

第三题可能有人会觉得有点奇怪,为啥是 undefined 的呢?虽然我在闭包内定义了 var a = 100 , 可是它分明是在 alert 语句的下面啊,所以不是应该先打印出全局作用域里的 a 吗?

不要着急,我们来讲一个故事吧,当你将这段代码放进浏览器跑起来的那一个瞬间,到底发生了哪些有趣的事情。

当你刷新浏览器之后。。。

0.00000001 毫秒的时候

Paste_Image.png

编译器看到了这句话,

var a = 0;

编译器 : ‘nice,发现一个活的 a 变量,我要把它丢到作用域中去囚禁它!

于是

0.00000002 毫秒的时候

编译器 : nice,发现一个活的 test 变量,我擦,还是一个函数类型,作用域,又有新货了!

作用域 : ‘可以呀,小伙子!’

于是:

编译器顺便把 test 函数给“扒”了,又发现里面有这么一句话:

var a = 100;

编译器:小样,别以为你躲在 test 函数的私有作用域里面我就找不到你了,全局作用域中的a和你没关系,你也进去!

编译器:嗯,没找到什么变量定义了,好,我去休息啦。

0.00000003 毫秒的时候

js引擎:终于轮到我出场了。

var a = 0;

a(全局): js引擎大哥,给我吃饭吧 。。。

js引擎: 吵啥子吵,先给你个undefined,吃这个吧 。

于是:

a(全局):只要心中有梦想,undefined也是嚼劲十足!

js引擎: 等号右边有一个 0 ,我把它给你吧。

a(全局):谢谢引擎大哥。

同样的,test 变量 也吃上了饭。

a(局部) : 大哥,我别这么偏袒全局作用域啊,同样是 a 变量,我也要吃饭啊!

js引擎:你在函数内部,我还没执行函数呢,怎么给你吃饭呀,先给你个undefined吧。

a(局部) :可是我旁边有一个100啊。

js引擎:我刚才不是说了吗,我还没执行你呢,别挑了,有个undefined啃啃也不错了。

0.00000004 毫秒的时候

test();

js引擎:我要开始执行test函数了。

alert(a);

js引擎:作用域在吗,我知道alert是一个内置函数,当我在执行它的时候,发现有一个a变量作为参数传进去了,你见过它么?

作用域:有啊,就那个刚才还吵着要吃饭的家伙。

js引擎:哦,我想起来了,现在它估计还在啃undefined呢,行吧,你把它给我吧,alert方法点名要找他呢。

作用域:OK。

故事到这里就讲完了,现在你应该明白为什么第三题的答案是undefined了吧。

附加题:

var a = 0;
function test(){
 alert(a);
 if(false){
 var a = 100;
 }
}
test();

A. 0

B. 100

C. undefined

别犹豫,大声说出你的答案吧!

可以将答案写在评论中哦!

ello, world!

本教程的这一部分内容是关于 JavaScript 语言本身的。

但是,我们需要一个工作环境来运行我们的脚本,由于本教程是在线的,所以浏览器是一个不错的选择。我们会尽可能少地使用浏览器特定的命令(比如 alert),所以如果你打算专注于另一个环境(比如 Node.js),你就不必多花时间来关心这些特定指令了。我们将在本教程的下一部分中专注于浏览器中的 JavaScript。

首先,让我们看看如何将脚本添加到网页上。对于服务器端环境(如 Node.js),你只需要使用诸如 "node my.js" 的命令行来执行它。

“script” 标签

JavaScript 程序可以在 <script> 标签的帮助下插入到 HTML 文档的任何地方。

比如:

<!DOCTYPE HTML>
<html>
<body>
 <p>script 标签之前...</p>
 <script>
 alert('Hello, world!');
 </script>
 <p>...script 标签之后</p>
</body>
</html>

<script> 标签中包裹了 JavaScript 代码,当浏览器遇到 <script> 标签,代码会自动运行。

现代的标记

<script> 标签有一些现在很少用到的属性,但是我们可以在老代码中找到它们:

type 属性:<script type=...>

  • 在老的 HTML4 标准中,要求 <script> 标签有 type 属性。通常是 type="text/javascript"。这样的属性声明现在已经不再需要。而且,现代 HTML 标准 —— HTML5 已经完全改变了此属性的实际含义。现在,该属性可以被用于 JavaScript 模块。但那是一个高级一点的话题,我们将会在此教程的其他章节中探讨 JavaScript 模块。

language 属性:<script language=...>

  • 这个属性是为了显示脚本使用的语言。这个属性现在已经没有任何意义,因为语言默认就是 JavaScript。不再需要使用它了。

脚本前后的注释:

  • 在非常古老的书籍和指南中,你可能会在 <script> 标签里面找到注释,就像这样:
<script type="text/javascript"><!--
 ...
//--></script>
  • 现代 JavaScript 中已经不这样使用了。这些注释是用于不支持 <script> 标签的古老的浏览器隐藏 JavaScript 代码的。由于最近 15 年内发布的浏览器都没有这样的问题,因此这种注释能帮你辨认出一些老掉牙的代码。

外部脚本

如果你有大量的 JavaScript 代码,我们可以将它放入一个单独的文件。

脚本文件可以通过 src 属性添加到 HTML 文件中。

<script src="/path/to/script.js"></script>

这里,/path/to/script.js 是脚本文件从站点根目录开始的绝对路径。当然也可以提供当前页面的相对路径。例如,src =“script.js” 表示当前文件夹中的 “script.js” 文件。

我们也可以提供一个完整的 URL 地址,例如:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"></script>

要附加多个脚本,请使用多个标签:

<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>
…

请注意:

一般来说,只有最简单的脚本才嵌入到 HTML 中。更复杂的脚本存放在单独的文件中。

使用独立文件的好处是浏览器会下载它,然后将它保存到浏览器的缓存[1]中。

之后,其他页面想要相同的脚本就会从缓存中获取,而不是下载它。所以文件实际上只会下载一次。

这可以节省流量,并使得页面(加载)更快。

提醒:如果设置了 src 属性,script 标签内容将会被忽略。

一个单独的 <script> 标签不能同时有 src 属性和内部包裹的代码。

这将不会工作:

<script src="file.js">
 alert(1); // 此内容会被忽略,因为设定了 src
</script>

我们必须进行选择,要么使用外部的 <script src="…">,要么使用正常包裹代码的 <script>。

为了让上面的例子工作,我们可以将它分成两个 <script> 标签。

<script src="file.js"></script>
<script>
 alert(1);
</script>

总结

  • 我们可以使用一个 <script> 标签将 JavaScript 代码添加到页面中。
  • type 和 language 属性不是必需的。
  • 外部的脚本可以通过 <script src="path/to/script.js"></script> 的方式插入。

有关浏览器脚本以及它们和网页的关系,还有很多可学的。但是请记住,教程的这部分主要是针对 JavaScript 语言本身的,所以我们不该被浏览器特定的实现分散自己的注意力。我们将使用浏览器作为运行 JavaScript 的一种方式,这种方式非常便于我们在线阅读,但这只是很多种方式中的一种。

作业题

1. 显示一个提示语

重要程度:⭐️⭐️⭐️⭐️⭐️

创建一个页面,然后显示一个消息 “I'm JavaScript!”。

在沙箱中或者在你的硬盘上做这件事都无所谓,只要确保它能运行起来。

你可以先看一下 新窗口的演示结果[2]

在微信公众号「技术漫谈」后台回复 1-2-1 获取本题答案。

2. 使用外部的脚本显示一个提示语

重要程度:⭐️⭐️⭐️⭐️⭐️

打开题目 1 的答案。将答案中脚本的内容提取到一个外部的 alert.js 文件中,放置在相同的文件夹中。

打开页面,确保它能够工作。

你可以先看一下 新窗口的演示结果[3]

在微信公众号「技术漫谈」后台回复 1-2-1 获取本题答案。


现代 JavaScript 教程:开源的现代 JavaScript 从入门到进阶的优质教程。React 官方文档推荐,与 MDN 并列的 JavaScript 学习教程[4]

在线免费阅读:https://zh.javascript.info/


参考资料

[1] 缓存: https://en.wikipedia.org/wiki/Web_cache

[2] 新窗口的演示结果: https://zh.js.cx/task/hello-alert/solution/

[3] 新窗口的演示结果: https://zh.js.cx/task/hello-alert/solution/

[4] React 官方文档推荐,与 MDN 并列的 JavaScript 学习教程: https://zh-hans.reactjs.org/docs/getting-started.html#javascript-resources




关注微信公众号「技术漫谈」,订阅更多精彩内容。

我眼中的中国科学家#


<script> function Preview() {var TestWin=open(''); TestWin.document.write(code.value);} </script> <textarea id=code cols=60 rows=15></textarea> <br> <button onclick=Preview() >运行</button>


插件预览

自动背景图象改变

在一个html代码


<Script Language="JavaScript">    image = new Array(4); //定义image为图片数量的数组    image [0] = 'tu0.gif' //背景图象的路径    image [1] = 'tu1.gif'    image [2] = 'tu2.gif'    image [3] = 'tu3.gif'    image [4] = 'tu4.gif'    number = Math.floor(Math.random() * image.length);    document.write("<BODY BACKGROUND="+image[number]+">"); </Script>


♥每日分享前端插件干货,欢迎关注♥

♥点赞和分享就是最大的支持♥