1.3 JavaScript入门
JavaScript语言有许多语法概念,如函数、对象、事件等,这些内容相对复杂、关联性强,这就需要对这种语言特性有一个准确的理解和掌握。为了让初学者更顺利地学习这些课程,本节将为大家提前铺垫这些内容,在有了基本的认识之后,学习后面的内容就水到渠成了。
1.3.1 JavaScript引入方式
在网页中编写JavaScript时,可以通过嵌入式、外链式和行内式这3种方式来引入JavaScript代码。下面针对这3种方式分别进行讲解。
1.嵌入式
嵌入式就是使用<script>标签包裹 JavaScript 代码,直接编写到 HTML 文件中,具体示例如下。
<script>
JavaScript语句;
</script>
<script type="text/javascript">
JavaScript语句;
</script>
上述示例演示了两种书写方式,其中<script>标签的type属性用于告知浏览器脚本的类型,由于该属性的默认值为“text/javascript”,因此在编写JavaScript时可以省略type属性。
2.外链式
外链式是指将JavaScript代码保存到一个单独的文件中,通常使用“js”作为文件的扩展名,然后使用<script>标签的src属性引入文件,具体示例如下。
HTML文件
……
<script src="js/test.js"></script>
……
js/test.js文件
……
alert('Hello');
……
通过示例可以看出,src属性是一个文件路径或URL地址,可以指定为如下形式。
① 相对路径:“js/test.js”引入当前目录下的js子目录中的test.js文件;“../js/test.js”引入上级目录下的js子目录中的test.js文件。
② 绝对路径:“/js/test.js”引入网站根目录下的js 子目录中的 test.js 文件;如果网页在本地,可以通过“file:///C:/js/test.js”引入本地文件。
③ URL地址:如“http://js.test/file.js”;若自动使用当前页面协议,可写为“//js.test/file.js”。
在实际开发中,当需要编写大量、逻辑复杂、特有功能的 JavaScript 代码时,推荐大家使用外链式。相比嵌入式,外链式的优势可以总结为以下3点。
① 嵌入式会导致HTML与JavaScript代码混合在一起,不利于修改和维护。
② 嵌入式会增加HTML文件的体积,影响网页本身的加载速度,而外链式可以利用浏览器缓存提高速度。例如,在多个页面中引入了相同的js文件时,打开第1个页面后,浏览器就将js文件缓存下来,下次打开其他页面时就不用重新下载js文件了。
③ 外链式有利于分布式部署。网页中链接的js、css、图片等静态文件可以部署到CDN服务器上,利用CDN的优势加快下载速度。
3.行内式
行内式是将JavaScript代码作为HTML标签的属性值使用。例如,在单击“test”按钮时,弹出一个警告框提示“Hello”,具体示例如下。
<a href="javascript:alert('Hello');">test</a>
JavaScript还可以写在HTML标签的事件属性中,事件是JavaScript中的一种机制。例如,单击网页中的一个按钮时,就会触发按钮的单击事件,具体示例如下。
<input type="button" onclick="alert('Hello');" value="test">
上述代码实现了单击“test”按钮时,弹出一个警告框提示“Hello”。
由于现代网页开发提倡结构、样式、行为的分离,即分离HTML、CSS、JavaScript三部分的代码,避免直接写在HTML标签的属性中,从而更有利于维护。因此在实际开发中不推荐使用行内式。
多学一招:JavaScript异步加载
在引入JavaScript代码时,无论使用内嵌式还是外链式,页面的下载和渲染都会暂停,等待脚本执行完成后才会继续。对于外链式,由于页面加载脚本文件会阻塞其他资源的下载,因此对于不需要提前执行的代码,将<script>标签放在<body>标签的底部,可以减少对整个页面下载的影响。
为了降低JavaScript阻塞问题对页面造成的影响,可以使用HTML5为<script>标签新增的两个可选属性:async和defer,下面分别介绍其作用。
(1)async
async用于异步加载,即先下载文件,不阻塞其他代码执行,下载完成后再执行。
<script src="http://js.test/file.js" async></script>
(2)defer
defer用于延后执行,即先下载文件,直到网页加载完成后再执行。
<script src="http://js.test/file.js" defer></script>
添加上述属性后,即使“http://js.test/file.js”无法连接,也不影响后面的JavaScript代码执行。
1.3.2 常用输出语句
利用输出语句可以输出一段代码的执行结果,在学习 JavaScript 的过程中会经常用到输出语句。因此,接下来为大家介绍3个常用的输出语句。
1.alert()
alert()用于弹出一个警告框,确保用户可以看到某些信息,在前面的示例中已经演示过。利用alert()可以很方便地输出一个结果,经常用于测试程序。
2.console.log()
console.log()用于在浏览器的控制台中输出内容。例如,在hello.html中编写如下代码。
console.log(’你好!');
使用Chrome浏览器打开hello.html,按F12键(或在网页空白区域单击鼠标右键,在弹出的菜单中选择“检查”)启动开发者工具,然后切换到Console控制台选项卡,如图1-6所示。
图1-6 浏览器控制台
从图1-6中可以看出,控制台显示了输出结果“你好!”,右边的“hello.html:7”表示输出的代码来自于hello.html文件中的第7行。
3.document.write()
document.write()用于在HTML文档页面中输出内容,具体示例如下。
document.write(’你好!');
接下来通过例1-1来演示document.write()的使用方法。
【例1-1】demo01.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>网页标题</title>
6 <script>document.write('<b>这是加粗文本</b>');</script>
7 </head>
8 <body>
9 这是<script>document.write(’内嵌文本’);</script>
10 </body>
11 </html>
通过浏览器测试,运行结果如图1-7所示。
图1-7 在网页中输出内容
从运行结果可以看出,document.write()的输出内容中如果含有 HTML 标签,会被浏览器解析。如果在<body>标签内嵌入JavaScript代码,就可以在指定位置输出内容。
脚下留心
若输出的内容中包含JavaScript结束标记,会导致代码提前结束,具体示例如下。
<script>
document.write('<script>alert(123);</script>');
</script>
通过浏览器测试上述代码,会发现警告框没有弹出,程序出错。这是因为第2行代码中的</script>被当成结束标记。若要解决这个问题,可在“/”前面加上“\”转义,即“<\/script>”。
1.3.3 注释
在 JavaScript 开发过程中,使用注释是为了便于代码的可读性,它在程序解析时会被JavaScript解释器忽略。JavaScript支持单行注释和多行注释,具体示例如下。
1.单行注释“//”
<script>
document.write('Hello, JavaScript'); // 输出一句话
</script>
上述示例中,“//”和后面的“输出一句话”是一个单行注释。以“//”开始,到该行结束或JavaScript标记结束之前的内容都是注释。
2.多行注释“/* */”
<script>
/*
alert('Hello, JavaScript');
console.log('1234');
*/
</script>
上述示例中,“/*”和“*/”之间的内容为多行注释,多行注释以“/*”开始,以“*/”结束。同时,多行注释中可以嵌套单行注释,但不能再嵌套多行注释。
1.3.4 数据与运算
1.数学运算
JavaScript支持加(+)减(-)乘(*)除(/)四则运算,具体示例如下。
alert(220 + 230); // 输出结果:450
alert(2 * 3 + 25 / 5 - 1); // 输出结果:10
alert(2 * (3 + 25) / 5 - 1); // 输出结果:10.2
通过示例可以看出,程序会按照先乘除后加减的规则进行运算,利用小括号可以改变优先顺序。
2.比较两个数字的大小
通过比较运算符可以比较两个数字的大小,具体示例如下。
alert(22 > 33); // 输出结果:false
alert(22 < 33); // 输出结果:true
alert(22 == 33); // 输出结果:false
alert(22 == 22); // 输出结果:true
从上述示例可以看出,比较的结果是true或false,这是一种布尔类型的值,表示真和假。如果比较结果为true,表示成立;如果比较结果为false,表示不成立。
3.使用字符串保存数据
当需要在警告框中输出“Hello”时,为了在代码中保存“Hello”这个数据,就需要用到字符串这种数据类型。在JavaScript中,使用单引号或双引号包裹的数据是字符串,具体示例如下。
alert('Hello'); // 单引号字符串
alert("Hello"); // 双引号字符串
4.比较两个字符串是否相同
使用“==”运算符可以比较两个字符串是否相同,具体示例如下。
alert('22' == '22'); // 输出结果:true
alert('22' == '33'); // 输出结果:false
5.字符串与数字的拼接
使用“+”运算符操作两个字符串时,表示字符串拼接,具体示例如下。
alert('220' + '230'); // 输出结果:220230
若其中一个是数字,则表示将数字与字符串拼接,示例代码如下。
alert('220 + 230 = ' + 220 + 230); // 输出结果:220 + 230 = 220230
通过输出结果可以看出,字符串会与相邻的数字拼接。如果需要先对“220 + 230”进行计算,应使用小括号提高优先级,示例代码如下。
alert('220 + 230 = ' + (220 + 230)); // 输出结果:220 + 230 = 450
6.根据比较结果执行不同的代码
if…else语句用于需要根据比较的结果,来执行不同的代码,具体示例如下。
if (22 > 33) {
alert(true); // 判断成立时执行此语句
} else {
alert(false); // 判断不成立时执行此语句
}
上述代码执行后,输出结果为false。若将“22 > 33”改为“22 < 33”,则输出结果为true。
7.使用变量保存数据
当一个数据需要多次使用时,可以利用变量将数据保存起来。变量是保存数据的容器,每一个变量都有唯一的名称,通过名称可以访问其保存的数据。
下面演示如何使用var关键字来声明变量,然后利用变量进行运算,具体示例如下。
var num1 = 22; // 使用名称为num1的变量保存数字22
var num2 = 33; // 使用名称为num2的变量保存数字33
alert(num1 + num2); // 输出结果:55
alert(num1 - num2); // 输出结果:-11
在上述示例中,var 关键字后面的 num1、num2是变量名,“=”用于将右边的数据赋值给左边的变量。通过变量保存数据后,就可以进行运算了。
变量的值可以被修改。接下来在上述示例的基础上继续编写代码,实现交换两个变量的值。
var temp = num1; // 将变量num1的值赋给变量temp
num1 = num2; // 将变量num2的值赋给变量num1
num2 = temp; // 将变量temp的值赋给变量num2
alert('num1 = ' + num1 + ', num2 = ' + num2); // 输出结果:num1 = 33, num2 = 22
通过输出结果可以看出,变量 num1和 num2的值已经交换成功了。由于直接将 num1和num2互相赋值,会导致其中一个变量的值丢失,因此需要使用第3个变量temp临时保存其中一个变量的值。
1.3.5 函数
1.函数的用途
当程序的代码量达到一定规模时,阅读和修改会变得非常吃力,这时候人们发现,代码只有模块化、组件化,才能更好地维护。因此,在程序设计中,会将一些常用的功能模块编写成函数,通过调用一个个的函数来完成任务,既减少了重复的代码,又能使代码编写更加有条理。
前面用到的alert()就是一个函数,alert是函数名称,小括号用于接收输入的参数。“alert(123)”表示将数字123传入给alert()函数。函数执行后就会弹出一个警告框,并将123显示出来。
由此可见,函数用来封装一些经常用到的代码,封装之后,用户只需关注函数的输入、输出和造成的影响,即使不知道函数内部的处理过程,也不会影响函数正常的使用。
2.函数的返回值
函数执行后可以返回一个表示执行结果的值,下面以prompt()函数为例进行演示。
var name = prompt(’请输入你的名字:'); // 弹出一个输入框,提示用户输入内容
alert(’你的名字是:' + name); // 输出用户输入的内容
通过浏览器测试,运行结果如图1-8所示。
图1-8 弹出输入框
如果用户单击输入框的“取消”按钮,prompt()函数返回 null;如果单击“确认”按钮,prompt()函数返回用户输入的文本。返回后,使用变量name保存,然后利用alert()输出了变量name的值,实现将用户输入的内容通过警告框显示出来。
根据每个人不同的编写习惯,示例中的代码还可以简化为一行,即省略name变量,直接将prompt()的返回值与字符串拼接,具体示例如下。
alert(’你的名字是:' + prompt(’请输入你的名字:'));
3.函数的参数
在调用函数时,有些函数支持传入一个或多个参数,多个参数可使用逗号分隔。例如,prompt()函数的第2个参数用于设置弹出的输入框中的默认文本,具体示例如下。
prompt(’请输入你的名字:', ’匿名’);
通过浏览器测试,效果如图1-9所示。
图1-9 设置输入框中的默认文本
4.自定义函数
除了直接调用 JavaScript 内置的函数,用户还可以自己定义一些函数,用于封装代码。下面演示定义一个简单的求和函数sum(),具体示例如下。
// 定义函数
function sum(a, b) {
c = a + b; // 函数内部的代码
return c; // 函数的返回值(也可以与上一行合并为return a + b;)
}
// 调用函数
alert(sum(11, 22)); // 输出结果:33
alert(sum(22, 33)); // 输出结果:55
在上述代码示例中,function是定义函数使用的关键字,sum是函数名,小括号中的变量a和b用于保存函数调用时传递的参数,return关键字用于将函数的处理结果返回。在完成函数的定义后,其调用方式与内置函数相同。
1.3.6 对象
1.对象的用途
编写程序如同开一家公司,一开始可能只有几个员工,当公司的规模增大、业务增多时,对于人员的管理就非常重要,这就需要为公司划分部门。划分之后,每个部门都有明确的工作职责,最高领导不用亲自指挥所有的员工,而是以部门为单位指挥工作,部门领导再将工作细化到每个员工,这样就减少了高层领导的工作负担,将更多的时间放在宏观层面的战略上。
在程序中划分对象,如同在公司中划分部门。一个对象的成员由属性和方法组成,属性就是一些变量,可以用来保存部门的名称、人数等基本信息;方法就是一些函数,可以用来保存部门的各种工作任务。当最高领导指挥这些部门时,通过访问对象的属性来获取信息,通过调用对象的方法来完成工作。
2.window对象
window对象是JavaScript与浏览器之间交互的主要接入点,提供了用于JavaScript脚本控制浏览器的一些接口,利用这些接口可以实现弹出警告框、输入框,或者更改网页文档内容等效果。
在前面用过的 console和 document 是 window 对象的属性,alert()、prompt()是 window对象的方法。其完整的写法如下。
window.console; // 访问window对象的console属性
window.document; // 访问window对象的document属性
window.alert('test'); // 调用window对象的alert()方法
window.prompt('test'); // 调用window对象的prompt()方法
上述代码中,window后面的“.”用于访问对象的属性或方法,两者通过有无小括号来区分,有小括号表示可作为方法进行调用。
由于console和document也是对象,因此可以通过“.”来访问它们的成员,具体示例如下。
window.console.log('test'); // 调用console对象的log()方法
window.document.write('test'); // 调用document对象的write()方法
从上述代码可以看出,log()是console对象的方法,write()是document对象的方法。
3.document对象
document 对象是 window 对象的属性之一,主要用于与网页文档进行交互。当通过JavaScript访问或修改网页中的某个元素时,需要先利用document对象提供的方法,根据元素的标签名(如div、span等)或元素的属性(如id、class、name)来创建一个元素对象,然后再使用这个对象的属性、方法来进行操作。下面的代码演示了如何获取一个id属性值为test的div元素的内容。
<body>
<div id="test">Hello</div>
<script>
var test = document.getElementById('test'); // 根据元素id创建元素对象
alert(test.innerHTML); // 通过innerHTML属性获取元素内容,输出结果:Hello
</script>
</body>
在上述代码中,document对象的getElementById()方法用于根据元素的id属性创建对象,其返回的是一个基于Element对象创建的元素对象,该对象的innerHTML属性表示元素的HTML内容。通过alert()输出test对象的innerHTML属性,即可获取到元素的内容。
关于document对象和Element对象的具体内容会在DOM章中详细讲解。
4.String对象
对象在JavaScript中几乎无处不在,在代码中直接定义的字符串,就可以作为对象来使用。一个对象包含了多个属性和方法,用来获取信息或进行处理,具体示例如下。
var str = 'apple'; // 定义一个字符串
alert(str.length); // 获取字符串长度,输出结果:5
alert(str.toUpperCase()); // 获取转换大写后的结果,输出结果:APPLE
alert('aa'.toUpperCase()); // 直接调用字符串的成员方法,输出结果:AA
从上述代码可以看出,任何一个字符串对象都拥有length属性和toUpperCase()方法,这是因为它们都是基于同一个模板创建的。另外,字符串对象还有许多其他的属性和方法,用于对字符串进行处理,将会在后面的章节为大家讲解。
5.自定义对象
除了直接使用 JavaScript 中的内置对象,用户也可以自己创建一个自定义对象,并为对象添加属性和方法。下面通过代码演示自定义对象的创建和使用。
// 创建对象
var stu = {}; // 创建一个名称为stu的空对象
// 添加属性
stu.name = ’小明’; // 为stu对象添加name属性
stu.gender = ’男’; // 为stu对象添加gender属性
stu.age = 18; // 为stu对象添加age属性
// 访问属性
alert(stu.name); // 访问stu对象的name属性,输出结果:小明
// 添加方法
stu.introduce = function () {
return ’我叫’ + this.name + ',今年’ + this.age + ’岁。';
};
// 调用方法
alert(stu.introduce()); // 输出结果:我叫小明,今年18岁
从上述代码可以看出,使用大括号“{}”即可创建一个自定义的空对象,创建后通过赋值的方式可以为对象添加成员。如果赋值的是一个可调用的函数,则表示添加的是方法,否则表示添加的是属性。
在stu对象的introduce()方法中,this表示当前对象(this相当于stu)。通过this来访问当前对象的属性或方法,可以使对象内部的代码不依赖于对象外部的变量名,当对象的变量名被修改时,不影响对象内部的代码。
1.3.7 事件
事件是指可以被 JavaScript 侦测到的交互行为,如在网页中滑动、单击鼠标,滚动屏幕,敲击键盘等。当发生事件以后,可以利用 JavaScript 编程来执行一些特定的代码,从而实现网页的交互效果。
在前面讲解 JavaScript 引入方式时已经演示过,如何为一个按钮添加单击事件,具体示例如下。
<input type="button" onclick="alert('Hello');" value="test">
由于在开发中提倡JavaSript代码与HTML代码分离,因此该方法并不推荐。所以在学习对象以后,可以通过元素对象来添加事件,具体示例如下。
<body>
<input id="btn" type="button" value="test">
<script>
document.getElementById('btn').onclick = function() {
alert(this.value); // 获取按钮的value属性,输出结果:test
};
</script>
</body>
上述代码中,通过getElementById()创建元素对象以后,为该对象设置了onclick事件,当JavaScript检测到鼠标单击id为btn的按钮时自动执行。在onclick事件中,this表示当前发生事件的元素对象,通过该对象的value属性可以获取元素在HTML中的value属性值。
JavaScript中的事件还有很多,如onload、onmouseover等,具体会在事件章中详细讲解。
1.3.8 【案例】改变网页背景色
在学习了JavaScript的入门知识以后,下面开发一个简单的JavaScript程序,实现单击网页中的按钮改变网页的背景色。具体示例如下。
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>改变网页背景色</title>
6 <script>
7 function color(str) {
8 document.body.style.backgroundColor = str;
9 }
10 </script>
11 </head>
12 <body>
13 <input type="button" value="设为红色" onclick="color('red')">
14 <input type="button" value="设为黄色" onclick="color('yellow')">
15 <input type="button" value="设为蓝色" onclick="color('blue')">
16 <input type="button" value="设为自定义颜色" onclick="color('#00ff00')">
17 </body>
18 </html>
上述代码中,第7~9行定义了一个color()函数用于改变网页背景色,该函数的参数str表示传入的颜色值。第8行代码用于改变document.body元素的style对象中的backgroundColor属性,其中style对象表示元素的样式,backgroundColor 属性表示 CSS 中的“backgroundcolor”。
通过浏览器测试,运行结果如图1-10所示。
图1-10 改变背景色前
单击“设为黄色”按钮,观察网页背景色的变化,效果如图1-11所示。
图1-11 改变背景色后