什么是JavaScript
JavaScript是一门跨平台、面向对象的脚本语言(即不需要编译就能直接运行),它用来控制网页行为,实现页面的交互效果。
组成:
ECMAScript:规定了JS基础语法核心知识,包括变量、数据类型、流程控制、函数、对象等。
BOM:浏览器对象模型,用于操作浏览器本身,如页面弹窗、地址栏操作、关闭窗口等。
DOM:文档对象模型,用于操作HTML文档,如:改变标签内的内容、改变标签内字体样式等。
JS引入方式
1.内部脚本:将JS代码定义在HTML页面中
JavaScript代码必须位于<script></script>标签之间
在HTML文档中,可以在任意地方,放置任意数量的<script>
一般会把脚本置于<body>元素的底部,可改善显示速度并防止报错。
2.外部脚本:将JS代码定义在外部JS文件中,然后引入到HTML页面中
内部脚本:
<!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>
//1.内部脚本
alert("Hello,JS");//分号可加可不加
</script>
</body>
</html>
效果:

外部脚本:
在html文件所在的目录下创建一个js文件夹,在js文件夹中创建demo.js,内容如下:
alert("hello,javascript");
html文件:
<!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>
<!-- 2.外部脚本 -->
<script src="js/demo.js"></script>
</body>
</html>
JS基础语法
变量与常量
JS中用let关键字来声明变量(弱类型语言,变量可以存放不同类型的值)
变量名要遵循以下规则:
1.只能由 字母、数字、下划线、美元符号组成,且数字不能开头
2.变量名严格区分大小写,如name和NAME是不同的变量
3.不能使用关键字,如:let\var\if\for等
JS中用const关键字来声明常量。一旦声明,常量的值就不能改变。
<!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>
//1.声明变量
let a = 10;
a = "tkevinjd";
a = true;
alert(a);
//2.声明常量
const PI = 3.14;
alert(PI);//alert是弹出框
PI = 3.1415;//错误写法,常量不可修改,但VSCode不会报错
console.log(PI);//console.log是控制台输出
</script>
</body>
</html>
效果如图:



输出到控制台,是输出到浏览器的控制台,我们可以进入浏览器后右键空白处,选择Inspect(检查)即可看到控制台。如果我们修改了常量,VSCode并不会报错,报错信息会显示在浏览器的控制台。
我们注释掉错误的那一行,再加入一个document.write(PI)
<!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>
//1.声明变量
let a = 10;
a = "tkevinjd";
a = true;
alert(a);
//2.声明常量
const PI = 3.14;
alert(PI);//alert是弹出框
//PI = 3.1415;//错误写法,常量不可修改,但VSCode不会报错
console.log(PI);//console.log是控制台输出
document.write(PI);//document.write是网页输出
</script>
</body>
</html>
新变化:

数据类型
JS虽然是弱类型语言,但是并不意味着它没有数据类型。JS的数据类型分为基本数据类型和引用数据类型(对象)。
基本数据类型:
1.number:数字(整数、小数、NaN(Not a Number))
2.boolean:true\false
3.null:对象为空。由于JS对大小写敏感,因此null\Null\NULL是完全不同的
4.undefined:当声明的变量未初始化时,该变量的默认值时undefined
5.string:字符串,用单引号、双引号、反引号包裹都可以
可以使用typeof运算符获取数据类型。
<!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>
//1.数据类型
console.log(typeof 10);
console.log(typeof 1.555);
console.log(typeof "tkevinjd");
console.log(typeof 'abc');
console.log(typeof `kevin`);//模板字符串
console.log(typeof true);
console.log(typeof false);
console.log(typeof null);
console.log(typeof undefined);
let a;
console.log(typeof a);
</script>
</body>
</html>
结果如图:
对于null,因为它表示对象为空,所以它的类型还是对象。
模板字符串使用反引号包裹,内容拼接变量时,使用${}包裹变量即可。
<!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>
//2.模板字符串
let name = "中野梓";
let age = 16;
console.log("轻音部的前辈们好,我叫" + name + ",今年" + age + "岁,请多多关照");
console.log(`轻音部的前辈们好,我叫${
name},今年${
age}岁,请多多关照`);
</script>
</body>
</html>
两个效果是一样的。使用模板字符串可以简化字符串拼接。
函数
JS中通过function关键字声明函数。在调用函数时,传递的参数个数和形参个数可以不一致。
<!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>
//1.函数定义与调用 - 具名函数
function add(a,b) {
return a + b;
}
console.log(add(1));//NaN
console.log(add(1,2));//3
console.log(add(1,2,3));//3
//2.函数定义与调用 - 匿名函数
//2.1 函数表达式
let res_sub = function(a,b) {
return a - b;
}
console.log(res_sub(1,2));//-1
//2.2 箭头函数
let res_mul = (a,b) => {
return a * b;
}
console.log(res_mul(2,3));//6
</script>
</body>
</html>
自定义对象
格式:
let 对象名 {
属性名1: 属性值1;
属性名2: 属性值2;
...
方法名: function(形参列表) {
}
}
调用对象的属性或方法同样通过打点完成。
<!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>
//1.自定义对象
let user = {
name: '平泽唯',
age: 18,
gender: '女',
playguitar() {
console.log(this.name + "正在弹吉他");
} //冒号与function可以省略
}
//2.调用对象属性与方法
console.log(user.name);
user.playguitar();
//注意:在箭头函数中,this并不指向当前对象,指向的是当前对象的父级
//在上面的例子中,this指向window对象
</script>
</body>
</html>
JSON
全称:JavaScript Object Notation,JavaScript对象标记法(JS对象标记法书写的文本)
由于其语法简单、层次结构分明,现多用于作为数据载体,在网络中进行数据传输
格式:
{
"name": "yui",
"age": 17,
"gender": "女"
}
JSON格式中所有的key都要用双引号包裹
需要注意的是,JS的对象和JSON格式的文本本质上是完全不同的,前者是代码操作的对象,后者只是字符串。
两个方法:
JSON.stringify(..):将JS对象转成JSON格式的字符串
JSON.parse(..):将JSON格式的字符串转成JS对象
类似Golang中的json.marshal和json.unmarshal
<!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>
let person = {
name: "埃尔文",
age: 34,
gender: "男"
};
alert(person);
console.log(person);
console.log(JSON.stringify(person));
</script>
</body>
</html>
效果如图:

<!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>
/*let person = {
name: "埃尔文",
age: 34,
gender: "男"
};
alert(person);
console.log(person);
console.log(JSON.stringify(person));
*/
let personJSON = '{"name":"埃尔文","age":34,"gender":"男"}';
console.log(personJSON);
console.log(JSON.parse(personJSON).name);//要转换为对象才能拿到属性
</script>
</body>
</html>
DOM
全称:Document Object Model,文档对象模型
将标记语言的各个组成部分封装为对应的对象:
Document:整个文档对象
Element:元素对象
Attribute:属性对象
Text:文本对象
Comment:注释对象
JS通过DOM,就能够对HTML进行操作。例如改变HTML元素的内容,改变HTML元素的样式(CSS),对HTML DOM事件作出反应,添加和删除HTML元素
DOM操作核心思想:将网页中所有的元素当作对象来处理。
获取DOM对象:
1.根据CSS选择器来获取DOM元素,获取匹配到的第一个元素:document.querySelector('选择器')
2.根据CSS选择器来获取DOM元素,获取匹配到的所有元素:document.querySelectorAll('选择器')
注意:得到的是一个NodeList节点集合,是一个伪数组(有长度、有索引的数组)
使用DOM的话,不建议看MDN,可以看这个:w3school 在线教程
<!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>
<h1 id="title1">11111</h1>
<h1>22222</h1>
<h1>33333</h1>
<script>
//1.修改第一个h1标签中的文本内容
//1.1获取DOM对象
let h1 = document.querySelector('#title1');
//或者let h1 = document.querySelector('h1');,选择的是匹配到的第一个元素
//如果是获取多个元素,则需要使用querySelectorAll,let h1s = document.querySelectorAll('h1');
//1.2调用DOM对象中的属性或方法
h1.innerHTML = "修改后的文本内容";
//如果获取多个元素,那么就要h1[0].innerHTML = "修改后的文本内容";
</script>
</body>
</html>
事件监听
HTML事件指发生在HTML元素上的事情,例如按钮被点击、鼠标移动到元素上、按下键盘按键等。事件监听指JS可以在事件触发时,就立即调用一个函数做出响应,也成为事件绑定或注册事件。
语法:事件源.addEventListener('事件类型',事件触发执行的函数)
事件监听三要素:
1.事件源:哪个DOM元素触发了事件,要获取元素
2.事件类型:用什么方式触发,比如:鼠标单击click
3.事件触发执行的函数:要做什么事
<!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>
<input type="button" id="btn1" value="点我一下试试">
<input type="button" id="btn2" value="点我一下试试">
<script>
document.getElementById('btn1').addEventListener('click', () => {
console.log('点击了按钮1')
})
document.getElementById('btn2').addEventListener('click', () => {
console.log('点击了按钮2')
})
</script>
</body>
</html>
早期的写法:事件源.on事件 = function(){...}
早期写法与addEventListener的区别在于:后者可以多次绑定同一事件,前者如果多次绑定同一事件只会多次覆盖。简单地说,就是对于addEventListener,对于btn1,你可以多次绑定click事件,每一次都执行不同的函数。那么当我们点击btn1时,这多个函数都会被执行。而对于早期写法,它只会执行最后绑定的函数,因为它会覆盖。
练习:实现表格数据行鼠标移入移出隔行换色效果
需求:针对上次的智能学习辅助系统,实现鼠标移入数据行时,背景色改为#f2e2e2,鼠标移出时,再将背景色改为白色。
新增代码:
<script>
//通过JS为上述表格中的数据行添加事件监听,实现鼠标进入后,背景色为#f2e2e2,鼠标离开后,背景色恢复为白色
document.querySelectorAll('tr').forEach(tr => {
tr.addEventListener('mouseenter', () => {
tr.style.backgroundColor = '#f2e2e2';
})
tr.addEventListener('mouseleave', () => {
tr.style.backgroundColor = '';
})
})
document.querySelectorAll('tr').forEach(tr => {
tr.addEventListener('click', () => {
tr.style.backgroundColor = '#f2e2e2';
})
})
</script>
常见事件
鼠标事件
click:鼠标点击
mouseenter:鼠标移入
mouseleave:鼠标移出
键盘事件
keydown:键盘按下触发
keyup:键盘抬起触发
焦点事件
focus:获得焦点触发
blur:失去焦点触发
表单事件
input:用户输入时触发
submit:表单提交时触发
模块化
在上面的练习中,我们加入了一段JS代码,但如果要加入的JS代码量比较大,则复用性与可维护性就会变差。因此我们需要将其单独抽取出来。
并且,如果多次调用console.log,建议将其抽取出来,放到一个单独的utils.js文件中。如果想要在另外的js文件中引入其它js文件的内容,依然可以像Java一样使用import关键字。例如:
import {
printLog} from "./utils.js";
那么要想把这个函数给别的文件使用,就要在本文件中将其暴露出来,即加上export关键字,类似于public
export function printLog(msg) {
console.log(msg);
}
如果使用了模块化的JS,那么我们要告诉HTML文件我们引入了模块化的JS,所以我们需要在HTML文件中引入JS的代码处再设置一个属性type,其值为module,表示我们使用的是模块化的JS:
<script src="/.js/name.js" type="module"></script>