JavaScript基础知识

本文最后更新于:1 年前

运行在客户端浏览器中的脚本语言,被网景公司发明,起初被用于浏览器中的数据校验。简称 js。

代码书写位置

script 标签中

1
2
3
<script>
console.log("hello world!");
</script>

.js 文件中

可以被编写到 js 文件中,再通过 script 标签引入:

1
<script src="app.js"></script>

但不可按如下方式编写:

1
2
3
<script src="app.js">
console.log("hello world!");// 此代码将不会生效
</script>

要么代码写到 app.js 中,要么把代码写到 script 标签中,不可以两边都写!

console.log

JavaScript 代码可以被编写到 script 标签中,使用 console.log 来输出:

1
2
3
<script>
console.log("hello world!");
</script>

输出的数据在浏览器的控制台中,打开浏览器控制台的方法有四种:

  • 鼠标右键点【检查】,在弹出的面板中点击【Console】
  • 菜单 –> 更多工具 –> 开发者工具
  • 快捷键:Ctrl + Shift + I
  • 快捷键:F12

几种输出类型

格式化输出

变量

声明变量

1
2
3
4
5
// 声明变量
var a = 10;
let b = 10;
// 声明常量
const c = 10;

var 与 let区别

1
2
3
4
5
6
7
8
9
10
11
// 使用 var 声明的变量,在大括号外依然可以使用
{
var a = 10;
}
console.log(a); //10

// 使用 let 声明的变量,在大括号外不可以使用
{
let b = 10;
}
console.log(b); //error: b is not defined

运算符

  • 赋值运算符:=+=-=*=/=%=
  • 关系运算符:><>=<===!====
  • 逻辑运算符:&&||!
  • 条件运算符:? :

+ 运算符

  • 当 + 两侧任意一个变量是字符串的时候,采用字符串拼接;
  • 如果两侧均为数字,则采用算术运算。
1
2
3
4
5
6
7
8
var a = 1 + 2;
console.log(a); //3
var b = 1 + "2";
console.log(b); //12
var c = "1" + 2;
console.log(c); //12
var d = "1" + "2";
console.log(d); //12

= 运算符

1
2
3
4
5
6
7
8
9
10
11
var a = 10;
var b = 10;
var c = "10";

// == 比较的是值(针对基础类型)
console.log(a == b); // true
console.log(a == c); // true

// === 不仅仅比较值,还要确保数据类型一致
console.log(a === b); // true
console.log(a === c); // false

数据类型

在 js 中,使用 typeof 可以识别变量的数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
var a = "10";
console.log(typeof a); // string
var b = 10;
console.log(typeof b); // number
var c = 3.14;
console.log(typeof c); // number
var d = true;
console.log(typeof d); // boolean 有且只有两个值:true、false
var e = null;
console.log(typeof e); // object
var f;
console.log(typeof f); // undefined 有且只有一个值:undefined

字符串

在 JavaScript 中,单引号和双引号都表示字符串。

1
2
3
4
var a = "hello";
console.log(typeof a); // string
a = 'a';
console.log(typeof a); // string

在 ES6 之后,推出了以反引号表示的字符串,称之为模板字符串,它有以下特点:

  • 可以使用 ${} 来获取字符串外部的变量的值
  • 可以在字符串中接受回车、换行、制表等特殊符号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = 6;
var y = 7;

// 反引号中,允许使用 ${} 表达式来获取字符串外部的变量的值
var a = `${x} x ${y} = ${x * y}`;

console.log(a);
// 单引号需要通过字符串拼接得到想要的输出数据
var s = x + ' x ' + y + ' = ' + x * y;
console.log(s);

var a = `hello
world`;
console.log(a); //输出结果也会换行

数字

无穷大 Infinity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 代表的是一个无穷大的数字
var a = Infinity;
console.log(a);
console.log(typeof a); // number

// 在js中允许除数为零, 其结果是无穷大
var b = 10 / 0;
console.log(b); //Infinity

// 无穷大和无穷大是相等的
console.log(a === b); //true
console.log(a === b + 1); //true
console.log(a === b + 100); //true
console.log(a === b + Infinity); //true

字符串转换为数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 方法一 parseInt: 将字符串转换为整数
var a = "3"; // string
var b = parseInt(a);
console.log(b); //3
console.log(typeof b);// number

// 方法二 parseFloat: 将字符串转换为小数
var c = "3.14";
b = parseFloat(c);
console.log(b);
console.log(typeof b); // number

// 方法三 直接进行算术运算
a = "10";
b = a - 0;
console.log(b);
console.log(typeof b); // number

a = "10";
b = a * 1;
console.log(b);
console.log(typeof b); // number

a = "10";
b = a / 1;
console.log(b);
console.log(typeof b); // number

a = "10";
b = a % Infinity;
console.log(b);
console.log(typeof b); // number

a = "123";
console.log(parseInt(a)); // 123
a = "a123";
console.log(parseInt(a)); // NaN

a = "1a23";
console.log(parseInt(a)); // 1
a = "123a";
console.log(parseInt(a)); // 123
// 在类型转换过程中,将会把第一个非数字及其后所有的内容全部舍掉,
// 如果第一个字符是非数字,则整体为非数字

非数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 在除法运算中,会自动进行数据类型转换
var a = "10" / "2";
console.log(a); // NaN: not a number

var b = 10 / "w";
console.log(b); // NaN
console.log(typeof b); // number

var c = 10 / "q";
console.log(c); // NaN
console.log(typeof c); // number

// 非数字 和 非数字 不相等
console.log(b == c); //false

// 使用 isNaN 方法判断变量是否是非数字
console.log(isNaN(b)); // true

精度

1
2
3
4
5
6
7
// 尽量避免使用 js 作算数运算, 可能产生精度问题
var a = 0.1 + 0.2;
console.log(a) //0.30000000000000004

/* 如果需要使用 js 作算数运算,可以通过 toFixed 方法保留小数位数
a.toFixed(1) 表示保留 1 位小数 */
console.log(a.toFixed(1)); // 0.3

流程控制

分支语句

1
2
3
4
5
6
7
8
var a = 10;
if (a % 2 == 0) {
console.log("偶数");
} else if (a % 7 == 0) {
console.log("7的倍数");
} else {
console.log("奇数");
}

循环语句

循环输出 1— 10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// for循环
for (let i = 1; i < 11; i++) {
console.log(i);
}

// while循环
var i = 1;
while (i < 11) {
console.log(i);
i++;
}

// do ... while循环
i = 1;
do {
console.log(i);
i++;
} while (i < 11);

九九乘法表

  • 如果积比 10 小,则前位补零,例如:2 x 2 = 04。
  • 每个计算表达式使用制表位分隔。
1
2
3
4
5
6
7
8
9
for (let x = 1; x < 10; x++) {		// 行
let s = "";
for (let y = 1; y <= x; y++) { // 列
let z = x * y;
z = (z < 10 ? "0" : "") + z;
s += `${x} x ${y} = ${z} `;
}
console.log(s);
}

JS操作 DOM

如果为一个 HTML 元素设置 id,这个id可以作为 js 变量在 js 代码中直接使用:

1
2
<h1 id="n">H1</h1>
<script> console.log(n); </script>
  • 通过 innerText 可以获取或修改元素的里面的文本内容
  • 通过 innerHTML 可以获取或修改元素的里面的超文本内容
1
2
3
4
5
// innerText 用于获取或设置元素中的 文本内容
n.innerText = '请假了';

// innerHTML 用于获取或设置元素中的 超文本内容
n.innerHTML = '饶梓桓<i>请假</i>了';

九九乘法表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
span {
background-color: blue;
color: white;
margin-left: 10px;
margin-right: 10px;
margin-bottom: 10px;
display: inline-block;
}
</style>

<div id="d"></div>
<script>
var dom = "";
for (let x = 1; x < 10; x++) {
dom += "<div>";
for (let y = 1; y <= x; y++) {
let z = x * y;
// 前位补零
z = (z < 10 ? "0" : "") + z;
dom += `<span>${x}x${y}=${z}</span>`;
}
dom += "</div>";
}
d.innerHTML = dom;
</script>

字符串函数

charAt

charAt 用于获取字符串中指定下标位置的字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 0123456789
var a = "hello world";

// 获取下标为 1 的字符
console.log(a.charAt(1)); //e

// length 用于获取字符串的长度
console.log(a.length); //11

// 遍历字符串,挨个获取所有的字符
for (let i = 0; i < a.length; i++) {
let c = a.charAt(i);
console.log(c);
}

indexOf 和 lastIndexOf

查找指定字符串第一次出现的位置的下标。

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = "hello world";

// 从左往右查找指定的字符串,并返回其下标
var i = a.indexOf("l");
console.log(i); // 2

// 从右往左查找指定的字符串,并返回其下标
i = a.lastIndexOf("l");
console.log(i); // 9

// 如果返回的是 -1, 则说明不存在字符 z
i = a.indexOf("z");
console.log(i); // -1

substr 和 substring

按下标切割字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = "hello world";

// 从 from 开始截取,截 length 个字符。 如果没有 length 参数,则一直截取到末尾
// substr(from: number, length?: number)
var s = a.substr(3, 2); // 从 3 开始,截取两个字符
console.log(s); //lo

// 从 start 开始截取,截到 end 结束
// 截取的字符串,包含开始不包含结束
// 如果没有 end 参数,则截取到末尾
// substring(start: number, end?: number)
s = a.substring(3, 6); // 从 3 开始,截到 6(不含6)
console.log(s); //lo

split

按照指定的字符进行字符串切割。

1
2
3
var a = "1,2,3,4,5";
var ns = a.split(",");
console.log(ns); //['1', '2', '3', '4', '5']

trim

返回去除前后空格的新字符串。

1
2
3
4
5
6
var a = " Hello ";

console.log(a.length); // 20
a = a.trim();
console.log(a.length); // 5
console.log(a); // Hello

toUpperCase 与 toLowerCase

将字符串转换大小写。

1
2
3
4
5
6
7
var a = "Hello";

var lc = a.toLowerCase();
console.log(lc); // hello

var uc = a.toUpperCase();
console.log(uc); // HELLO

小练习

1

现存在字符串 var s = " hello! I'm timor. "。试去除字符串中的前后空格,并将每个单词的首字母转大写 (不使用 split)。将调整之后的字符串显示到网页上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="d"></div>

<script>
var s = " hello! I'm timor. ";

for (let i = 0; i < s.length; i++) {
let c = s.charAt(i);
if (c === " ") { // 说明查找到了空格
//空格的下标是 i,则[0, i + 1) 全部保留,下标为 i + 1 的变大写,[i + 2, 末尾) 全部保留
s = s.substring(0, i + 1) + s.charAt(i + 1).toUpperCase() + s.substr(i + 2);
}
}

d.innerText = s.trim();
</script>

2

查询字符串 var s = "http://baidu.com/s?wd=你好李焕英&ie=utf-8;" 网址中,问号及其后面的部分被称之为查询字符串。对于一个网址,查询字符串的键是确定的,值是不确定的,如何获取 s 中键为 wd 的值。

1
2
3
4
5
6
var s = "http://baidu.com/s?wd=你好李焕英&ie=utf-8";
var i = s.indexOf("?wd=");
s = s.substr(i + 4);
i = s.indexOf("&");
s = s.substring(0, i);
console.log(s);

数组

声明数组

1
2
3
4
5
6
7
8
9
10
11
12
// 声明一个数组
var ns = [3, 6, 8];
console.log(ns); // [3, 6, 8]

// length 属性可以获取数组的长度
console.log(ns.length); //3

// 遍历数组中的每个元素
for (let i = 0; i < ns.length; i++) {
// 通过 [下标] 的形式获取或设置指定下标的值
console.log(i, ns[i]);
}

添加元素

  • push: 向数组的末尾增加一个元素。
  • unshift: 向数组的开头增加一个元素。
1
2
3
4
5
6
7
8
9
10
11
var ns = [3, 6, 8];

console.log( ns); // [3, 6, 8]

// push: 向数组的末尾增加一个元素
ns.push(9);
console.log( ns); // [3, 6, 8,9]

// unshift: 向数组的开头增加一个元素
ns.unshift(5);
console.log( ns); // [5,3, 6, 8,9]

删除元素

  • pop: 将数组的末尾的元素删除。
  • shift: 将数组的开头的元素删除。
1
2
3
4
5
6
7
8
9
10
var ns = [5, 3, 6, 8, 9];
console.log(ns); // [5, 3, 6, 8, 9]

// pop: 将数组的末尾的元素删除
ns.pop();
console.log(ns); // [5, 3, 6, 8]

// shift: 将数组的开头的元素删除
ns.shift();
console.log("ns=>", ns); // [3, 6, 8]

查找元素

  • indexOf:从左往右查找指定元素并返回下标。
  • lastIndexOf:从右往左查找指定元素并返回下标。
1
2
3
4
5
6
7
8
9
10
11
12
13
var ns = [5, 3, 6, 8, 9];

// 在数组中从左往右查找指定元素并返回下标
var i = ns.indexOf(6);
console.log(i); // 2

// 在数组中从右往左查找指定元素并返回下标
i = ns.lastIndexOf(6);
console.log(i); // 2

// 如果在数组中没有查找到指定的元素,则返回 -1
i = ns.lastIndexOf(5);
console.log(i); // -1

删除的同时增加元素

splice 方法从指定下标开始删除指定个数的元素,同时从该下标处增加元素,被删除的元素将会组合成为一个新的数组并返回。

1
splice(start: number, deleteCount?: number)
  • start: 从哪个下标开始删除。
  • deleteCount:删除多少个。如果没有 deleteCount 参数,则表示从 start 开始一直删除到末尾。
  • 自第三个参数开始,表示需要往 start 下标开始插入的数据。
  • 该方法返回的结果是被删除的元素的集合。
1
2
3
4
5
6
7
8
9
10
var ns = [3, 6, 8];
console.log(ns); // [3, 6, 8]


// 从下标为 1 开始删除,删除 2 个,然后在下标为 1 的位置增加 5 和 7 两个元素
var rs = ns.splice(1, 2, 5, 7);
console.log(ns); // [3, 5, 7]

//返回的结果是被删除的元素的集合。
console.log(rs); // [6, 8]

判断变量是数组

使用 Array.isArrayinstanceof 判断变量是否是数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var ns = [3, 6, 8];
console.log(ns); // [3, 6, 8]

console.log(typeof ns); // object

// 1. Array.isArray 判断变量是否是数组
if (Array.isArray(ns)) {
console.log("ns 是数组");
}

// 2. instanceof 判断变量是否是数组
if (ns instanceof Array) {
console.log("ns 是数组");
}

数学函数

取整

1
2
3
4
5
6
7
8
9
10
11
// 四舍五入 : Math.round
console.log(Math.round(3.4)); // 3
console.log(Math.round(3.5)); // 4

// 向下取整 : Math.floor
console.log(Math.floor(3.4)); // 3
console.log(Math.floor(3.5)); // 3

// 向上取整 : Math.ceil
console.log(Math.ceil(3.4)); // 4
console.log(Math.ceil(3.5)); // 4

伪随机数

Math.random: 取值范围是:[0, 1) 区间。

1
2
3
// 伪随机数 :Math.random, 取值范围是:[0, 1) 区间
var r = Math.random();
console.log(r); // 3.22122

小练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// [0, 10)
var a = Math.floor(Math.random() * 10);

// [5, 15)
var b = 5 + Math.floor(Math.random() * 10);

// (5, 15]
var c = 5 + Math.ceil(Math.random() * 10);

// [m, n) 若m、n 均为正整数,且m<n,在 [m, n) 区间内生成随机整数
var m = 5;
var n = 12;
var d = m + Math.floor(Math.random() * (n - m));
console.log(d);

// 随机点名
var ns = ["张三", "李四", "王五", "赵六"];
// 数组下标的取值范围是:[0, ns.length)
var i = Math.floor(Math.random() * ns.length);
// 将随机下标取出的姓名显示到 h1 上
h.innerText = ns[i];

日期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 获取当前时间
var d = new Date();
console.log(d); // Mon May 23 2022 03:30:43 GMT+0800 (中国标准时间)

// 获取四位数的年份
var year = d.getFullYear();
console.log(year); // 2022

// 获取月份, 从 0 开始
var month = d.getMonth();
console.log(month); //4

// 获取在一个月中的天数, 也就是几号
var date = d.getDate();
console.log(date); // 23

// 获取小时
var hour = d.getHours();
console.log(hour); // 3

// 获取分钟
var minute = d.getMinutes();
console.log(minute); // 30

// 获取秒数
var second = d.getSeconds();
console.log(second); // 42

// 获取毫秒数
var millisecond = d.getMilliseconds();
console.log(millisecond); // 415

// 获取今天是一周的第几天,也就是周几
// 一周的第一天是周日, 从 0 开始计算
var week = d.getDay();
console.log(week); // 1

// 获取当前时间的时间戳
var t = d.getTime();
console.log(t); // 1653247950415

//修改当前时间
d.setDate(21);
d.setMonth(5);
// 当日期发生变化后,其他的时间属性将会跟随变化
console.log(d); // Tue Jun 21 2022 03:32:30 GMT+0800 (中国标准时间)
1
2
3
4
5
6
7
8
9
10
11
12
推算出距离今天100天后的日期是:?年?月?日

// 方法一:
var a = new Date();
var ms = a.getTime() + 100 * 24 * 60 * 60 * 1000;
a.setTime(ms);
console.log(a);

// 方法二:
var b = new Date();
b.setDate(b.getDate() + 100);
console.log(b);

计时器

setTimeout

该函数有两个参数,分别是执行的代码延迟的时间

第一个参数:可以是代表 js 代码的字符串,也可以是一个函数的名称,或者是 λ 表达式,或者是匿名函数。
第二个参数:指的是延迟的时间,单位是:ms。(仅执行一次)。

1
2
3
4
5
6
7
var js = 'console.log("你好呀");';

var i = setTimeout(js, 3000);
// setTimeout 可以返回一个数字,

// 该数字用于 clearTimeout 来提前关闭计时器
clearTimeout(i);

setInterval

该函数有两个参数分别是执行的代码延迟的时间

第一个参数:可以是代表 js 代码的字符串,也可以是一个函数的名称,或者是 λ 表达式,或者是匿名函数。
第二个参数:指的是延迟的时间,单位是:ms。(在之后间隔这个时间不断执行

1
2
3
4
5
6
7
var js = 'console.log("你好呀");';

var i = setInterval(js, 3000);
// setInterval 可以返回一个数字,

// 该数字用于 clearInterval 来关闭计时器
clearInterval(i);
1
2
3
4
5
每隔 1s 输出一句话,大约 10s 后不再输出这句话。

var js = 'console.log("你好呀");';
var i = setInterval(js, 1000);
setTimeout('clearInterval(i);', 10000);

JS 操作 DOM 样式

HTML 元素的样式最常见的控制方式是通过 style 属性和 class 属性来控制,只要通过 js 控制了 style 属性或 class 属性,即可控制 HTML 元素的样式。

操作 class 属性

通过元素的 className 属性可以获取或设置元素的 class 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
div {
width: 300px;
height: 400px;
}
.blue {
background-color: aqua;
}
.green {
background-color: aquamarine;
}
</style>

<div id="n" class="blue"></div>

<script>

// n代表的是 div 元素,n.className 代表的是 div 上的 class 属性
console.log(n.className) // blue
n.className = 'green' // 会将div修改为绿色
</script>

如果元素的 class 具备多个值,赋值的时候需要注意:

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
.a { width: 100px; height: 100px; }
.r { background-color: red; }
.g { background-color: green; }
</style>

<div id="d" class="a r"></div>

<script>
console.log(d.className);
d.className = "a g"; //如果只写g会失去a的样式
console.log(d.className);
</script>

操作 style 属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
div { width: 100px; height: 100px;}
</style>

<div id="d" style="background-color: red;" ></div>

<script>
// 当且仅当 style 属性中存在的样式才可以获取。当 style 属性中没有 width 的时候,无法通过d.style.width 获取此时的宽度
console.log(d.style.width); // 无信息

// 无论 style 属性中是否存在 width, 都可以通过 d.style.width 对其进行设置宽度
d.style.width = "200px";
console.log(d.style.width);

// 在 style 属性中的连字符需要采用小驼峰命名法来替换
d.style.backgroundColor = "green";
</script>

小练习

  • 每隔 1s 为正方形随机设置一个颜色。

  • 每隔 1s 增加正方形的边框半径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<style>
div { width: 100px; height: 100px; }
</style>

<div id="d" style="background-color: red;" ></div>

<script>
// 每隔 1s 为这个正方形随机设置一个颜色
var js = `
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
d.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
`;
setInterval(js, 1000);

// 每隔 1s 增加这个正方形的边框半径
var jsc = `
var r = d.style.borderRadius;
// 将边框半径的字符串形式转换为数字形式
r = parseInt(r);
// 如果 r 是非数字,则设置为 0
r = isNaN(r) ? 0 : r;
r++;
d.style.borderRadius = r + "px";
`;
setInterval(jsc, 1000);
</script>

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!