JavaScript 基础
JavaScript 教程
网页的四层结构
网页由四层信息构成,共同实现功能与展示效果:

- 内容层:网页核心内容
- 结构层:内容的组织形式,由标准语言描述
- 表现层:内容的显示样式,由标准语言定义
- 行为层:内容对事件的响应方式,由标准语言控制
各层对应的标准语言
| 层级 | 标准语言 | 说明 |
|---|---|---|
| 结构层 | XML(可扩展标记语言)、XHTML(可扩展超文本标记语言) | 描述网页内容的组织结构 |
| 表现层 | CSS(层叠样式表) | 定义网页内容的显示样式 |
| 行为层 | DOM(文档对象模型)、ECMAScript(ECMA 制定的标准脚本语言) | 控制网页的交互行为 |
补充:HTML 具备弱表现描述能力,CSS 可通过 hover 伪类实现简单响应行为。
什么是 JavaScript
- JavaScript 是一种脚本语言,专为 HTML 页面添加交互性设计。
- 通常直接嵌入 HTML 页面,无需预先编译,属于解释型语言。
- 无需购买许可证,可免费使用。
JavaScript 的组成
ECMAScript 是标准化的脚本程序语言规范,定义了基本语法,不与浏览器绑定。Flash 中的 ActionScript 及 JavaScript 均是其具体实现。
JavaScript 能做什么
- 为 HTML 页面添加动态内容,读写 HTML 元素。
- 对事件作出反应,验证表单数据。
- 检测浏览器类型,创建 cookies。
- 是互联网上最流行的脚本语言,支持所有主流浏览器。
如何在 HTML 中插入 JavaScript
JavaScript 需嵌入 HTML 才能生效,插入方式有三种:
行内式(嵌入到 HTML 标记的事件中)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>导入js的方式1:行内式</title>
</head>
<body>
<a onclick="return confirm('are you sure')" href="../1.html" style="color: red;">返回</a>
</body>
</html>
- 效果:点击链接会弹出确认框,点击“取消”不跳转,点击“确定”跳转到
../1.html页面。


嵌入式(使用 script 标记对嵌入网页)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>导入js的方式2:嵌入式</title>
<script>
document.write("<p>hello world</p>")
</script>
</head>
<body>
</body>
</html>
- 效果:页面直接显示“hello world”。

链接式(通过 script 标记的 src 属性链接外部脚本文件)
步骤1:新建外部 JS 文件(如 index.js)

/**
* 外部链接式
*/
/**
* 函数
*/
function test() {
alert("Hello JavaScript!")
}
/**
* 调用
*/
test()
步骤2:在 HTML 中链接外部 JS 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>导入js的方式3:链接式</title>
<script src="../../scripts/index.js"></script>
</head>
<body>
</body>
</html>
- 效果:页面加载时弹出“Hello JavaScript!”提示框。

- 注意:script 标签不能使用单标签,导入时会将 JS 内容复制到
<script>和</script>之间。
JavaScript 语言基础
JavaScript 变量
- JavaScript 变量为弱类型,无特定类型限制,用
var/let/const声明,可初始化为任意值,且能修改数据类型(不建议)。 - 示例:
var name = "Six Hang"; var age = 28; var school = "CSU"; var male = true;
变量命名规范
- 第一个单词全小写,后续单词首字母大写(小驼峰命名法),如
sMyString。 - 首字符必须是字母、下划线(_)或美元符号($)。
- 后续字符可包含字母、数字、下划线、美元符号。
- 不能是关键字或保留字,对大小写敏感。
- 不能包含空格、回车符或其他标点字符。
ES6 新特性:let 和 const
/**
* js 中的变量,弱类型,用 var/let 声明
* ES6 新特性: let 和 const
* let 声明的变量,块级作用域
* const 声明的变量,常量,不能修改
*/
var username = 'peppa'
console.log("username变量类型:", typeof username)
// 可以随意改变变量中所存储的数据类型,当然为了程序规范应该避免这样操作
username = 100
console.log("username变量类型:", typeof username)
for (var i = 0; i < 10; i++) {}
// i 可以在循环外访问
console.log("迭代完成,i = ", i)
// 若用 let 声明变量,则 i 只能在循环内部访问
for (let j = 0; j < 10; j++) {}
// console.log("迭代完成,j = ", j) // 报错,块级作用域只在块级有效
const PI = 3.14
// PI = 3.1415 // 不能修改常量,会报错
console.log用于在浏览器控制台输出内容。





变量命名原则(非法示例)
var 5zhao;// 数字开头,非法var tang's;// 包含单引号,非法字符var this;// 使用关键字,非法
运算符
运算符用于对一个或多个值进行运算,产生结果值,参与运算的值称为操作数。
算术运算符
| Operator | Description | Example | Result |
|---|---|---|---|
| + | 加法 | x=2, y=2 | x+y = 4 |
| - | 减法 | x=5, y=2 | x-y = 3 |
| * | 乘法 | x=5, y=4 | x*y = 20 |
| / | 除法 | 15/5, 5/2 | 3, 2.5 |
| % | 取模(余数) | 5%2, 10%8, 10%2 | 1, 2, 0 |
| ++ | 自增 | x=5, x++ | x=6 |
| -- | 自减 | x=5, x-- | x=4 |
赋值运算符
| Operator | Example | Is The Same As |
|---|---|---|
| = | x=y | x=y |
| += | x+=y | x=x+y |
| -= | x-=y | x=x-y |
| *= | x*=y | x=x*y |
| /= | x/=y | x=x/y |
| %= | x%=y | x=x%y |
比较运算符
| Operator | Description | Example |
|---|---|---|
| == | 等于(仅比较值) | 58 → false;x=5, y="5" → xy → true |
| === | 全等(比较值和类型) | x=5, y="5" → x===y → false |
| != | 不等于 | 5!=8 → true |
| > | 大于 | 5>8 → false |
| < | 小于 | 5<8 → true |
| >= | 大于等于 | 5>=8 → false |
| <= | 小于等于 | 5<=8 → true |
逻辑运算符
- JS 中逻辑运算返回短路处的值。
- 示例:
let resValue = 100 || ("peppa" && "")→ 100(或运算遇 true 短路,返回第一个值)。
| Operator | Description | Example |
|---|---|---|
| && | 逻辑与 | x=6, y=3 → (x<10 && y>1) → true |
| || | 逻辑或 | x=6, y=3 → (x5 || y5) → false |
| ! | 逻辑非 | x=6, y=3 → !(x==y) → true |
字符串连接运算符
- 用
+运算符连接两个或多个字符串。 - 示例:
txt1 = "What a very" txt2 = "nice day!" txt3 = txt1 + txt2 // txt3 结果为 "What a verynice day!"
条件运算符
- 语法:
var 变量名 = (条件) ? 值1 : 值2 - 示例:
greeting = (visitor == "PRES") ? "Dear President " : "Dear "- 若 visitor 等于 "PRES",greeting 为 "Dear President ";否则为 "Dear "。
JavaScript 中的数据类型
| 数据类型 | 布尔值判断规则 | 说明 |
|---|---|---|
| String(字符串) | 非空串为 true,空串为 false | 用单引号或双引号包裹 |
| number(数值) | 0 为 false,非 0 为 true | 不区分整型和浮点型 |
| boolean(布尔) | true/false | 不能用引号包裹(否则为字符串) |
| object(对象) | null 为 false,非 null 为 true | 复杂数据类型 |
| undefined(未定义) | false | 未初始化的变量值为 undefined |
| NaN(非数字) | false | 如 let result = "abc" * 100 → NaN |
字符串(String)
字符串定义
- 由零个或多个字符构成,字符可包括字母、数字、标点符号、空格。
- 必须放在单引号或双引号中,可使用转义字符
\输出特殊字符。 - 示例:
var course = "data structure"; var case = 'the birthday"19801106"'; var score = " run time 3\' 15\""; // 转义字符使用
JavaScript 中的转义字符
| Code | Outputs |
|---|---|
| ' | 单引号 |
| " | 双引号 |
| & | 和号 |
| \ | 反斜杠 |
| \n | 换行 |
| \r | 回车 |
| \t | 制表符 |
| \b | 退格 |
| \f | 换页 |
字符串对象常见属性和方法
定义示例字符串:var myString = "This is a sample";
| 属性/方法 | 说明 | 示例 | 结果 |
|---|---|---|---|
| length | 返回字符串长度 | var name = "Six tang"; name.length |
11 |
| charAt(index) | 返回指定位置的字符(索引从 0 开始) | myString.charAt(2) |
"i" |
| charCodeAt(index) | 返回指定位置字符的 10 进制 ASCII 码 | myString.charCodeAt(2) |
105 |
| indexOf(substr) | 返回子串在字符串中的起始位置 | myString.indexOf("is") |
2 |
| substr(start, length) | 截取字符串(起始位置,长度) | myString.substr(10, 3) |
"sam" |
| substring(start, end) | 截取字符串(起始位置,结束位置,不包含结束位置) | myString.substring(5, 9) |
"is a" |
| split(separator) | 按分隔符将字符串分割为数组 | var a = myString.split(" ") |
a[0]="This", a[1]="is", a[2]="a", a[3]="sample" |
| replace(old, new) | 替换字符串中的子串 | myString.replace("sample", "apple") |
"This is a apple" |
| toLowerCase() | 转换为小写字母 | myString.toLowerCase() |
"this is a sample" |
数值型(number)
-
不区分整型和浮点型,无需用引号包裹。
-
示例:
var num1 = 23.45; var num2 = 76; var num3 = -9e5; // 科学计数法,等价于 -900000 alert(num1 + " " + num2 + " " + num3); // 输出 "23.45 76 -900000"![image]()
-
字符串转数值:
let number1 = "200"; let number2 = "100"; let number3 = "50.20"; alert(parseInt(number1) + parseInt(number2) + parseFloat(number3) + number1 + " " + number2 + " " + number3);![image]()
布尔型(boolean)
- 取值仅为
true和false,不能用引号包裹(否则为字符串)。 - 用
typeof()可判断数据类型:var married = true; document.write(typeof(married) + "<br />"); // 输出 "boolean" married = "true"; document.write(typeof(married)); // 输出 "string"
数组(array)
数组声明
- 用
[]或new Array()声明,可指定长度。 - 示例:
let list1 = [] let list2 = new Array(10) // 创建长度为 10 的数组 list2[9] = 100 console.log("list1:", list1) console.log("list2:", list2)![image]()
数组的常用属性和方法
| 属性/方法 | 说明 | 示例 | 结果 |
|---|---|---|---|
| length | 获取数组长度 | var Map = new Array("China", "USA", "Britain"); Map.length |
3 |
| toString() | 将数组转为字符串 | Map.toString() |
"China,USA,Britain" |
| push(item) | 向数组末尾添加元素,返回新长度 | let list = []; list.push(1); list.push(2); |
数组变为 [1,2] |
| pop() | 删除并返回数组最后一个元素 | list.pop() |
2,数组变为 [1] |
| shift() | 删除并返回数组第一个元素 | list.shift() |
1,数组变为 [] |
| unshift(items) | 向数组开头添加元素,返回新长度 | list.unshift(1,2,3) |
3,数组变为 [1,2,3] |
| splice(start, deleteCount, items) | 删除元素并添加新元素 | let list = ['peppa', 'lili', 'lucy']; list.splice(1,1,'lala','lulu') |
数组变为 ['peppa', 'lala', 'lulu', 'lucy'] |
数组作为栈使用
let list = [];
list.push(1);
list.push(2);
console.log(list.pop());
console.log(list.pop());

数组作为队列使用
let list = [];
list.push(1);
list.push(2);
console.log(list.shift());
console.log(list.shift());

数组作为双端队列使用
let list = [];
// unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
console.log(list.unshift(1, 2, 3));
console.log(list);
// push() 方法可向数组的末尾添加一个或更多元素,并返回新的长度。
console.log(list.push(4, 5, 6));
console.log(list);
// pop() 方法从数组中删除最后一个元素,并返回该元素的值。
console.log(list.pop());
console.log(list);
// shift() 方法从数组中删除第一个元素,并返回该元素的值。
console.log(list.shift());
console.log(list);

splice
删除某个元素,添加元素。第一个参数为删除的起始位置,第二个参数为删除的个数,第三个参数以后为添加的元素
let list = ['peppa', 'lili', 'lucy'];
// splice 删除某个元素,添加元素 第一个参数为删除的起始位置,第二个参数为删除的个数,第三个参数为添加的元素
list.splice(1, 1, 'lala', 'lulu') // 删除下标为1的元素,添加两个元素
console.log(list)
list.splice(2, 2, 'lala', 'lulu') // 删除下标为2开始的2个元素,添加两个元素
console.log(list)

set 集合
- 无序不重复的集合。
- 示例:
let set = new Set(); set.add(1); set.add(2); set.add(3); set.add(4); console.log(set.size); // 4 set.delete(2); console.log(set.size); // 3 set.forEach(item => console.log(item)); // 1, 3, 4![image]()
map
- 键值对集合,键可以是任意类型。
- 示例:
let map = new Map(); map.set('name', 'peppa'); map.set('age', 18); map.set('sex', 'female'); console.log(map.get('name')); // "peppa" console.log(map.has('name')); // true map.delete('name'); console.log(map.size); // 2 map.forEach((value, key) => { console.log(key, value); // "age 18", "sex female" });![image]()
JavaScript 中的语句
条件语句
用于根据条件判断执行不同的代码块,包括 if 语句、if else 语句和 switch 语句。
if else 语句
var d = new Date();
var time = d.getHours();
if (time < 10) {
document.write("<b>Good morning</b>");
} else if (time > 10 && time < 16) {
document.write("<b>Good day</b>");
} else {
document.write("<b>Hello World!</b>");
}
switch 语句
evalue = parseInt(prompt("请输入1-4对我们的服务做出评价",""));
switch(evalue){
case 1: document.write("非常满意"); break; // break 防止穿透
case 2: document.write("满意"); break;
case 3: document.write("一般"); break;
case 4: document.write("不满意"); break;
default: document.write("您的输入有误!");
}


循环语句
用于重复执行一段代码,包括 while 循环、for 循环、for…in 语句。
while 循环
var i = 0;
while (i < 10) {
document.write(i + "<br>");
i++;
}

for 循环(九九乘法表)
for (var i = 1; i < 10; i++) { // 乘法表一共九行
document.write("<tr>"); // 每行是 table 的一行
for (j = 1; j < 10; j++) { // 每行都有9个单元格
if (j <= i) { // 有内容的单元格
document.write("<td style='border:2px solid #004B8A; background: white;'>" + i + "*" + j + "=" + (i * j) + " </td>");
} else { // 没有内容的单元格
document.write("<br>");
break;
}
}
document.write("</tr>");
}

for…in 语句(遍历对象/数组)
在有些情况下,开发者根本没有办法预知对象的任何信息,更谈不上控制循环的次数。这个时候用for…in语句可以很好的解决这个问题。
var x;
var mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
for (x in mycars) {
document.write(mycars[x] + "<br />");
}

函数
函数是可重用的代码块,用于完成特定功能,可接收参数并返回结果。
函数定义语法
function functionname(arg1, arg2, ..., argX) {
statements;
[return [expression];] // 可选,返回结果
}
函数调用示例
示例1:带参数,无返回值
function myName(sName) {
alert("Hello" + sName);
}
// 调用
myName("six-tang"); // 弹出 "Hellosix-tang"

示例2:带参数,有返回值
与其他编程语言一样,函数在执行过程中只要执行完return语句就会停止继续执行函数体中的代码,因此return语句后的代码都不会执行。下例中函数中的alert()语句就永远都不会执行。
function fnSum(iNum1, iNum2) {
return iNum1 + iNum2;
alert(iNum1 + iNum2); // 永远不会执行(return 后代码终止)
}
console.log(fnSum(10, 20)); // 输出 30

示例3:多 return 语句
一个函数中有时可以包含多个return语句,但每次只有一个会被执行,例如:
function substr(iNum1, iNum2) {
if (iNum1 >= iNum2) {
return iNum1 - iNum2;
} else {
return iNum2 - iNum1;
}
}
alert(substr(10, 5)); // 弹出 5

示例4:无参数 return 语句(退出函数)
如果函数本身没有返回值,但又希望在某些时候退出函数体,则可以调用无参数的return语句来随时返回函数体,例如:
function myName(sName) {
if (myName == "bye") {
alert("Goodbye");
return;
}
alert("Hello" + sName);
}
myName("bye"); // 弹出 "Goodbye"

ES6 函数新特性
箭头函数
-
简洁写法,不绑定自身
this,继承外层作用域的this。 -
示例:
// 普通函数 function add(a, b) { return a + b; } // 箭头函数(无大括号时直接返回表达式结果) const addArrow = (a, b) => a + b; // 单个参数可省略括号 const addArrow2 = a => a + 1; // 多句代码需加大括号和 return const addArrow3 = (a, b) => { console.log("a = ", a); console.log("b = ", b); return a + b; };![image]()
-
注意:对象方法中不建议使用箭头函数(
this指向父级):let car = new Object(); car.color = 'red'; car.type = 'SUV'; car.brand = 'Benz'; car.run = function() { console.log(`${this.color}:${this.brand}:${this.type} is running...`); }; car.run2 = () => { console.log(`${this.color}:${this.brand}:${this.type} is running...`); // this 指向父级为 window,属性 undefined }; car.run(); // 正常输出 car.run2(); // 输出 "undefined:undefined:undefined is running..."![image]()
参数默认值
// ES6 前(短路运算实现默认值)
function add(num1, num2) {
num1 = num1 || 0;
num2 = num2 || 0;
return num1 + num2;
}
// ES6 新特性(直接指定默认值)
function add(num1 = 0, num2 = 0) {
return num1 + num2;
}
// 箭头函数 + 默认值
const add = (num1 = 0, num2 = 0) => num1 + num2;
可变参数
// 普通函数
function sum(a, ...number) {
let sum = a;
for (let number in number) {
sum += number;
}
return sum;
}
// 箭头函数 + 可变参数
const sumArrow = (a, ...numbers) => {
let sum = a;
for (let number in numbers) {
sum += number;
}
return sum;
};
全局变量(函数中未声明的变量)
function test() {
username = 'peppa'; // 未声明,自动成为全局变量
}
test();
console.log(username); // 输出 "peppa"

对象
对象是特定实体的抽象,包含描述特性的属性(变量)和操作特性的方法(函数)。
对象的创建方式
new Object() 创建空对象
let car = new Object();
car.color = 'red';
car.type = 'SUV';
car.brand = 'Benz';
car.run = function() {
console.log(`${this.color}:${this.brand}:${this.type} is running...`);
};
car.run(); // 输出 "red:Benz:SUV is running..."

函数工厂创建对象
function createCar(color, type, brand) {
let car = new Object();
car.color = color;
car.type = type;
car.brand = brand;
car.run = function () {
console.log(`${this.color}:${this.brand}:${this.type} is running...`);
};
return car;
}
let car1 = createCar("red", "car", "BMW");
car1.run(); // 输出 "red:BMW:car is running..."
let car2 = createCar("yellow", "bus", "Tesla");
car2.run(); // 输出 "yellow:Tesla:bus is running..."

构造方法创建对象
function Car(color, brand, type) {
this.color = color;
this.brand = brand;
this.type = type;
this.run = function () {
console.log(`${this.color}:${this.brand}:${this.type} is running...`);
};
}
var car1 = new Car('red', 'Benz', 'Sedan');
car1.run(); // 输出 "red:Benz:Sedan is running..."

对象直接量(字面量)创建
let name = 'peppa';
let age = 10;
let gender = "Female";
// 普通字面量
let peppa = {
name: name,
age: age,
gender: gender,
study: function () {
console.log(`${this.name} is studying.`);
}
};
peppa.study(); // 输出 "peppa is studying."
// ES6 新特性:对象字面量简写
let peppa2 = {
name, // 等价 name: name
age, // 等价 age: age
gender, // 等价 gender: gender
birthday: '2019-01-01',
study() { // 方法简写,等价 study: function(){}
console.log(`${this.name} is studying.`);
}
};
peppa2.study(); // 输出 "peppa is studying."

原型 prototype 动态添加属性和方法
针对已经定义好的对象进行动态添加。
// 已定义的构造函数
function Car(color, brand, type) {
this.color = color;
this.brand = brand;
this.type = type;
this.run = function () {
console.log(`${this.color}:${this.brand}:${this.type} is running...`);
};
}
// 动态添加属性
Car.prototype.price = 10000;
// 动态添加方法
Car.prototype.show = function () {
console.log(`${this.color}:${this.brand}:${this.type} is ${this.price}`);
};
var car = new Car('red', 'Benz', 'SUV');
car.price = 20000;
car.run(); // 输出 "red:Benz:SUV is running..."
car.show(); // 输出 "red:Benz:SUV is 20000"

ES6 新特性:class(语法糖)
class Person {
// 构造方法与Java不一样,这儿的构造方法名与类名不一样
constructor(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
// 方法
greet() {
return "Hello, my name is " + this.name + " and I am " + this.age + " years old"
}
// 静态方法
static isAdult(age) {
return age >= 18
}
}
//JS 也支持继承
class Student extends Person {
constructor(name, age, gender, grade) {
// super 调用父类的构造方法
super(name, age, gender)
this.grade = grade
}
study() {
return this.name + " is studying in grade " + this.grade
}
greet() {
// 调用父类的方法
return super.greet() + " I am in grade " + this.grade
}
}
var person = new Person("Peppa", 10, "Female")
console.log(person.greet())
var student = new Student("Lily", 12, "Female", 5)
console.log(student.study())
console.log(student.greet())
console.log(Person.isAdult(16))
console.log(Student.isAdult(20))

迭代对象中的属性
for in 迭代
class Person {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
greet() {
return "Hello, my name is " + this.name + " and I am " + this.age + " years old";
}
}
var person = new Person("Peppa", 10, "Female");
for (var key in person) {
console.log(key + ": " + person[key]);
}

for of 与解构赋值(ES6 新特性)
let list = [1, 2, 3, 4, 5];
// for of 迭代数组元素
for (let item of list) {
console.log(item); // 依次输出 1,2,3,4,5
}
// 解构赋值:从数组中提取元素赋值给变量
let [a, b, c, d, e] = list;
console.log(a, b, c, d, e); // 输出 "1 2 3 4 5"

展开运算(ES6 新特性)
class Person {
constructor(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
greet() {
return "Hello, my name is " + this.name + " and I am " + this.age + " years old"
}
}
let p = new Person("Peppa", 5, "girl")
// 展开运算
let p1 = {...p} // 创建一个对象,对象属性与 p 一致
let p2 = {...p, name: "Lily"} // 创建一个对象,对象属性与 p 一致,但 name 属性被修改
// 展开运算不会有方法
// console.log(p1.greet()) // 报错
console.log(p1)
console.log(p2)
let p3 = {...p, grade: 1} // 创建一个对象,对象属性与 p 一致,新增 grade 属性
console.log(p3)









浙公网安备 33010602011771号