JavaScript基础

组成部分


  • ECMAScript,描述了该语言的语法和基本对象。
  • 文档对象模型(DOM),描述处理网页内容的方法和接口。
  • 浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口。

特点


  1. 是一种解释性脚本语言(代码不进行预编译)。
  2. 主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。
  3. 可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。
  4. 跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、iOS等)。

html引入js

  • 在 HTML 中引入 JavaScript 有两种常见的方式:

    1. 直接写在 <script> 标签里

      • 在 HTML 文件中,可以直接使用 <script> 标签来编写 JavaScript 代码,例如:

        1
        2
        3
        <script>
        // JavaScript 代码在这里
        </script>
      • 这种方式适用于简单的 JavaScript 代码,但对于较大的项目或多个文件的情况,不够灵活和维护。

    2. 外部引入

      • 另一种更常见的方式是将 JavaScript 代码编写在外部文件中,然后在 HTML 文件中通过 <script> 标签引入外部文件,例如:

        1
        <script src="hello.js"></script>
      • 这样做的好处是可以将 JavaScript 代码和 HTML 结构分离,提高了代码的可维护性和可复用性。同时,也方便了浏览器对 JavaScript 文件的缓存和加载管理。

    关于注释,JavaScript 和 Java 的注释方式类似,主要有单行注释 // 和多行注释 /* ... */。单行注释用于注释一行代码或部分代码,多行注释用于注释多行或大段代码。例如:

    1
    2
    3
    4
    5
    6
    7
    // 这是单行注释

    /*
    这是
    多行
    注释
    */

    在 HTML 中,也可以使用类似的注释方式。例如:

    1
    <!-- 这是 HTML 注释 -->

    这些注释方式可以提高代码的可读性和可维护性,让其他开发者更容易理解代码的意图。

基本语法

js严格区分大小写

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Basics</title>
</head>
<body>

<script>
// 定义一个变量 num,赋值为 1
var num = 1;

// 使用 if-else 条件语句判断 2 是否大于 1
if (2 > 1) {
// 如果条件成立,弹出警告框显示 "true"
alert("true");
} else {
// 如果条件不成立,弹出警告框显示 "false",但这里的代码不会被执行
alert("false");
}

// 将变量 num 的值打印到浏览器控制台
console.log(num);
</script>

</body>
</html>

  1. 定义变量

    1
    var num = 1;
    • 使用 var 关键字定义了一个名为 num 的变量,并将其赋值为 1
  2. 条件控制

    1
    2
    3
    4
    5
    if (2 > 1) {
    alert("true")
    } else {
    alert("false")
    }
    • 使用 if 语句来进行条件判断。

    • 判断条件是 2 > 1。因为这个条件是 true(2确实大于1),所以执行 if 语句块中的代码:

      1
      alert("true")
      • alert("true") 会在浏览器中弹出一个警告框,显示消息 "true"。
    • 如果条件不成立(即条件为 false),那么会执行 else 语句块中的代码:

      1
      alert("false")
      • 但是在这种情况下,else 块中的代码不会被执行,因为 2 > 1true
  3. 浏览器控制台打印

    1
    console.log(num);
    • console.log(num); 会将变量 num 的值打印到浏览器的控制台中。在这段代码中,控制台中会显示 1

这段代码首先定义了一个变量 num 并赋值为 1,然后判断 2 > 1 是否为真,并根据判断结果在浏览器中弹出一个警告框,最后在控制台中打印 num 的值。运行结果如下:

  • 浏览器会弹出一个显示 "true" 的警告框。
  • 控制台中会显示 1

变量

JavaScript 中可以使用 varletconst 关键字来声明变量。

  1. var 声明
    • 在 ES5 及之前的版本中常用的声明方式。
    • 变量声明的作用域为所在的函数内(函数作用域),如果在函数内未使用 var 声明,则变量成为全局变量。
    • 存在变量提升(hoisting)的特性,即变量可以在声明之前使用。
    • 在循环中声明的变量在每次迭代后不会被销毁,而是被提升到循环作用域的顶部。
  2. let 声明
    • 在 ES6 中引入的新的声明方式。
    • 变量声明的作用域为所在的代码块内(块级作用域)。
    • 不会存在变量提升,变量只能在声明之后被访问,不存在暂时性死区(Temporal Dead Zone)。
    • 在循环中声明的变量会在每次迭代结束后被销毁,不会像 var 那样在循环外部保留。
  3. const 声明
    • 也是在 ES6 中引入的新的声明方式。
    • 声明一个常量,常量的值在声明后不能被修改。
    • 其他特性和 let 声明类似,也具有块级作用域和不存在变量提升的特性。

因此,在现代 JavaScript 开发中,推荐使用 letconst 来声明变量,避免了 var 声明可能带来的一些问题,提高了代码的可读性和安全性。

基本数据类型

数值

  1. 整数和小数
    • JavaScript 中的数值类型统一表示为浮点数,无论是整数还是小数,都被视为 number 类型。例如,11.0 都是 number 类型的值。
  2. NaN(Not a Number)
    • NaN 是一种特殊的数值,表示“不是一个数字”。
    • 当某些操作无法返回正确的数值时,就会产生 NaN。比如将非数值字符串转换为数字、0 除以 0 等操作都会返回 NaN。
    • NaN 与任何值(包括它自己)进行比较都返回 false。可以使用 isNaN() 函数来检测一个值是否为 NaN。
  3. Infinity(无穷大)
    • Infinity 是数值类型的一个特殊值,表示正无穷大。
    • 当某些数值超出了 JavaScript 数值的表示范围时,就会被转换为 Infinity。
    • 例如,1 / 0Number.POSITIVE_INFINITY 都会得到 Infinity。
    • 正无穷大与任何大于 0 的数值相乘都得到正无穷大,与任何小于 0 的数值相乘都得到负无穷大。
  4. 负无穷大
    • JavaScript 中也有负无穷大,表示为 -Infinity
    • 与正无穷大类似,负无穷大与任何小于 0 的数值相乘都得到正无穷大,与任何大于 0 的数值相乘都得到负无穷大。

数值类型在 JavaScript 中是非常常用的,它们用来进行算术运算、存储数字数据等。对于特殊情况如 NaN 和 Infinity 的处理,需要注意避免产生意外的结果。

字符串

在 JavaScript 中,字符串是一种表示文本数据的基本数据类型。字符串可以由单引号 '...' 或双引号 "..." 包围。

  1. 单引号和双引号

    • JavaScript 中字符串可以使用单引号或双引号来表示,例如:'Hello'"World"
    • 单引号和双引号在大多数情况下是等效的,可以根据个人偏好选择使用哪一种。
  2. 转义字符

    • 在字符串中,可以使用反斜杠 \ 来转义特殊字符,例如 \' 表示单引号,\" 表示双引号,\n 表示换行符等。
  3. 字符串拼接

    • 使用加号 + 可以将多个字符串拼接在一起,例如 'Hello' + ' ' + 'World' 将得到字符串 'Hello World'
  4. 字符串长度

    • 可以使用字符串对象的 length 属性获取字符串的长度,例如 'Hello'.length 将返回 5。
  5. 访问字符

    • 可以使用方括号 [] 和索引来访问字符串中的单个字符,例如 'Hello'[0] 将返回字符 'H'
  6. 模板字符串(ES6 新增):

    • 使用反引号 `...` 包围的字符串,支持多行字符串和字符串插值(将变量或表达式嵌入字符串中),例如:

      1
      2
      let name = 'World';
      let greeting = `Hello, ${name}!`;

布尔值

true fasle

逻辑运算符

  • && 与
  • || 或
  • ! 非

比较

  • = 赋值
  • == 等于(类型不一样,但是值一样,也会返回true)
  • === 绝对等于(类型一样并且值一样,才会返回true)
  • 这是js的缺陷,尽量不使用==比较

    浮点数问题: console.log((1/3)===(1-2/3)) 结果为false,尽管数值是都等于1/3 尽量避免使用小数计算,因为精度问题

注意:

  • 一般使用三等号,不使用双等号。

  • 特殊的 NaN===NaN 返回false,使用方法isNaN(NaN)返回true

  • 浮点数问题:精度损失,尽量避免浮点数运算。

    需要比较时使用精度判断:Math.abs(a-b)<0.0000001再认为相等。

  • null和undefined

    • null是定义为空
    • undifined是值未定义

严格检查模式

'use strict'; 是 JavaScript 中的一种指令,用于启用严格模式(strict mode)。严格模式是 ES5 中引入的一种更加严格的 JavaScript 解析和执行模式,它对一些不安全或不规范的语法和行为进行了限制,从而提高了代码的质量和安全性。

  1. 启用严格模式
    • 'use strict'; 声明将代码置于严格模式下,启用严格模式后,JavaScript 引擎会对代码进行更严格的解析和执行。
    • 严格模式可以应用于整个脚本文件,也可以仅应用于函数体内部。
  2. 主要特点
    • 变量必须声明后再使用,否则会抛出 ReferenceError。
    • 禁止删除变量或函数声明。
    • 禁止删除不可删除的属性。
    • 函数参数不能有同名属性,否则会抛出语法错误。
    • 禁止使用八进制数字。
    • 对象不能有重复的属性名,否则会抛出语法错误。
    • 函数不能有重复的参数名,否则会抛出语法错误。
    • 禁止使用 with 语句。
    • evalarguments 不能被重新赋值。
    • 禁止使用 arguments.calleearguments.caller
    • 严格模式下的 this 值为 undefined
    • 等等,还有更多限制。
  3. 优势和好处
    • 提高代码的安全性和可靠性,避免一些常见的错误。
    • 减少了代码的隐式转换和不确定性行为,使代码更易于理解和维护。
    • 使 JavaScript 更接近传统编程语言的行为,提高了代码的可预测性。

推荐在 JavaScript 代码的开头加上 'use strict'; 声明,以启用严格模式,确保代码更加规范、安全和可靠。

数组

中括号表示

java的数值必须是相同类型的对象,js中不一样,数组课存放不同类型

可以存储不同类型的元素

创建数组

  • 可以使用字面量方式直接创建数组,也可以使用 new Array() 构造函数来创建数组。例如:
1
2
3
var arr1 = [1, 2, 'a', 'b']; // 使用字面量方式创建数组
var arr2 = new Array(1, 2, 'a', 'b'); // 使用构造函数创建数组

下标从0开始,越界则返回undefined

类似python中的列表

  • length 长度可变
  • indexOf()
  • slice() 截取数组的一部分,类似python中的切边
  • push() 添加元素 尾部
  • pop() 弹出元素 尾部
  • shift() 弹出元素 头部
  • unshift() 添加元素 头部
  • sort() 排序
  • reverse() 反转
  • join() 使用字符拼接,类似python
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
// 创建一个数组
var arr = [1, 2, 3, 4, 5];

// 获取数组的长度
console.log("数组的长度:", arr.length);

// 查找元素的索引
console.log("元素 3 的索引:", arr.indexOf(3));

// 截取数组的一部分
var slicedArr = arr.slice(1, 3);
console.log("截取的数组:", slicedArr);

// 添加元素到尾部
arr.push(6);
console.log("添加元素后的数组:", arr);

// 弹出尾部元素
var poppedItem = arr.pop();
console.log("弹出的元素:", poppedItem);
console.log("弹出元素后的数组:", arr);

// 弹出头部元素
var shiftedItem = arr.shift();
console.log("弹出的头部元素:", shiftedItem);
console.log("弹出头部元素后的数组:", arr);

// 添加元素到头部
arr.unshift(0);
console.log("添加元素到头部后的数组:", arr);

// 排序数组
arr.sort();
console.log("排序后的数组:", arr);

// 反转数组
arr.reverse();
console.log("反转后的数组:", arr);

// 使用字符拼接数组元素
var joinedString = arr.join('-');
console.log("拼接后的字符串:", joinedString);

字符串

  • 单引号或双引号
  • 转义字符也是反斜杠
  • 多行字符串可以直接用反引号包裹
  • 模板字符串:字符串里拼接变量
1
2
3
4
5
6
7
8
9
10
11
// unicode编码的汉字中国
console.log("\u4e2d\u56fd");

// 多行字符串可以直接用反引号包裹
console.log(`abc
def`)

// 模板字符串:字符串里拼接变量
let name = "Peter";
let hello = `你好,${name}`;
console.log(hello)

这段JavaScript代码展示了如何使用Unicode编码表示汉字、多行字符串以及模板字符串来拼接变量。以下是逐行解释:

  1. Unicode编码的汉字

    1
    console.log("\u4e2d\u56fd");
    • \u 是Unicode转义序列的前缀,紧随其后的四个十六进制数字表示一个Unicode字符。
    • \u4e2d 对应的字符是汉字 "中"。
    • \u56fd 对应的字符是汉字 "国"。
    • 所以,console.log("\u4e2d\u56fd"); 会在控制台中输出 "中国"。
  2. 多行字符串

    1
    2
    console.log(`abc
    def`)
    • 使用反引号(`)来创建多行字符串。

    • abcdef 位于不同的行。

    • console.log(\abc`);` 会在控制台中输出:

      1
      2
      abc
      def
  3. 模板字符串:字符串里拼接变量

    1
    2
    3
    let name = "Peter";
    let hello = `你好,${name}`;
    console.log(hello)
    • 使用反引号(`)来创建模板字符串。
    • ${} 语法用于在字符串中嵌入变量或表达式。
    • let name = "Peter"; 定义了一个变量 name,并赋值为 "Peter"
    • let hello = \你好,${name}`;创建了一个模板字符串,其中嵌入了变量name` 的值。
    • console.log(hello); 会在控制台中输出 "你好,Peter"。

总结:

  • 使用Unicode转义序列 \u 可以表示汉字,并在控制台输出。
  • 反引号(`)可以用来创建多行字符串。
  • 模板字符串可以通过 ${} 语法在字符串中嵌入变量或表达式,并在控制台中输出带有嵌入变量的字符串。

字符串有哪些属性和方法?

  • length 长度
  • [下标] 访问字符串中的单个字符
  • 字符串和java的字符串同样是不可变的(都是常量)
  • toUpperCase()、toLowerCase() 转换大小写
  • indexOf() 或者某个字符在字符串中的下标
  • substring(1,3) 截取字符串 [,)左闭右开

对象

若干个键值对,类似python中的字典。获取对象类型:typeof 变量名。

大括号表示,很像python的字典,但是取值用点就行了,person.name。(实测使用中括号加key的方式也能取到值)

键只能是字符串

1
2
3
4
5
6
7
8
<script>
var person = {
name: "Huijie",
age: 23,
hobby: ['code', 'movie', 'music']
};
</script>

  • 属性不存在时返回undefined,不会报错
  • 动态删除属性 delete person.name
  • 动态添加属性 person.haha = "haha"
  • 判断属性是否在对象中 'age' in person,注意所有的对象都有'toString'属性,是继承来的
  • 判断一个属性是否是这个对象本身拥有的:hasOwnproperty()

if语句

1
2
3
4
5
6
7
// 流程控制
let age = 23;
if (age>=18) {
console.log("成年了")
} else {
console.log("未成年")
}

while循环

1
2
3
4
5
let i = 0;
while (i<10) {
console.log(i);
i++;
}

for循环

常用的不是for in,而是for of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (let j = 0; j < 10; j++) {
console.log(j)
}

for (let i in hobby) {
// 注意这里的i是下标,不是元素,和python不一样
console.log(hobby[i])
}

for (let i of hobby)
{
// 注意这里的i是元素了。。。
console.log(i)
}

遍历数组

注意forEach的参数要是个方法

1
2
3
4
5
let hobby = ['code', 'movie', 'music'];
hobby.forEach(function (value)
{
console.log(value)
})

map

键值对

1
2
3
4
5
6
7
let map = new Map([
["jim", 100],
["peter", 80]
]);
map.set("tim", 30);
console.log(map.get("jim"));
console.log(map.get("tim"));

set

无序不重复集合

1
2
3
let set = new Set(["a", "b", 1]);
set.add("a");
console.log(set)

iterator迭代器

1
2
3
4
5
let hobby = ['code', 'movie', 'music'];
for (let i of hobby)
{
console.log(i)
}

函数

function声明

方式一:

1
2
3
4
5
6
7
8
function abs(x) {
if (x > 0) {
return x;
} else {
return -x;
}
}
console.log(abs(-9));

方式二:(把匿名函数赋值给一个变量abs)

1
2
3
4
5
6
7
8
let abs = function (x) {
if (x > 0) {
return x;
} else {
return -x;
}
}
console.log(abs(-9));

参数问题:js非常不严谨,参数可以不传也可以任意多个,都不会报错,大不了返回undefined

没有传参如何规避?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let abs = function (x) 
{
// 规避未穿参数的情况,抛出异常
if (typeof x !== "number") {
throw 'Not a Number!'
}
if (x > 0)
{
return x;
} else
{
return -x;
}
}
console.log(abs());

arguments

是函数默认拥有的一个局部变量,是一个包含所有传进来的参数的数组:

1
2
3
4
5
function test(a, b, c) {
for (let a of arguments){
console.log(`传进来的参数有:${a}`)
}
}

rest

ES6新增的特性,获取除了已定义参数外的其它参数,rest只能写在最后面

1
2
3
4
5
6
7
8
function testRest(a, b, ...rest) 
{
for (let a of arguments)
{
console.log(`传进来的参数有:${a}`)
}
console.log(rest)
}

这段代码定义了一个名为 testRest 的函数,它接受两个普通参数 ab,以及一个 rest 参数 rest。以下是对代码的逐行解释:

  1. 函数定义

    1
    function testRest(a, b, ...rest) {
    • function testRest(a, b, ...rest) 定义了一个名为 testRest 的函数。
    • 这个函数接受两个普通参数 ab,以及一个 rest 参数 rest
    • rest 参数使用了 ... 语法,它允许函数接受任意数量的额外参数,并将这些参数收集到一个数组中。
  2. for 循环

    1
    2
    3
    for (let a of arguments) {
    console.log(`传进来的参数有:${a}`)
    }
    • for (let a of arguments) 循环遍历了函数内部的 arguments 对象。
    • arguments 对象包含了函数被调用时传入的所有参数,包括普通参数和 rest 参数。
    • 在循环中,每个参数的值都被打印出来,使用了模板字符串来构造输出的字符串。
  3. 打印 rest 参数

    1
    console.log(rest);
    • console.log(rest) 打印了 rest 参数的值。
    • 因为 rest 参数收集了除了已定义参数外的所有其它参数,所以 rest 是一个数组,包含了所有这些额外的参数。

总结:

  • 这段代码展示了如何在函数中使用 rest 参数来接收任意数量的额外参数,并将其收集到一个数组中。
  • arguments 对象可以用来访问函数被调用时传入的所有参数,包括普通参数和 rest 参数。

变量作用域

函数体内定义的变量是局部变量

一般把所有变量的声明都写在最前面,防止后面使用了未定义的变量。

全局对象window

默认所有定义在函数外的全局变量都会绑定到 全局对象 window 的属性(window就代表浏览器)

1
2
3
let x = 1;
console.log(window.x);
window.alert(x);

js实际上只有一个全局作用域window,任何变量(包括函数)。

(尽量避免全局命名冲突的)规范:

  • 由于所有全局变量都会绑定到window对象,不同的js文件如果定义了同名的变量会有冲突,所以出现了一种解决方式:自己定义一个全局对象,把所有变量都绑定到这个对象中:尽量避免全局命名冲突

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 当前文件的唯一全局变量
    let myApp = {};
    // 以后所有变量都绑定到myApp里,就不会和别的文件冲突
    myApp.name = "Huijie";
    myApp.add = function (a, b) {
    return a + b;
    }
    console.log(myApp.name)
    console.log(myApp.add(3,3))

解决局部作用域的问题

背景:使用var定义的局部变量在外边也能用,就可能会和别的地方冲突

1
2
3
4
5
for (var i = 0; i < 10; i++) {
console.log(i)
}
// 会打印出10
console.log(i)

ES6中新增了let方式定义变量,解决了这个问题:所以建议使用let声明变量

1
2
3
4
5
for (let i = 0; i < 10; i++) {
console.log(i)
}
// 这里会报错:Uncaught ReferenceError: i is not defined
console.log(i)

常量

ES6之前没有常量这个定义,只是一般用大写字母表示常量(实际还是可变的)

然后ES6有了const关键字来定义常量

1
2
3
const PI = 3.14;
// 报错:Uncaught TypeError: Assignment to constant variable.
PI = 3.2;

方法

对象里的函数,调用自己的属性用this

1
2
3
4
5
6
7
8
9
let Dog = 
{
name: "dog",
bark: function ()
{
console.log(this.name + " wang~ wang~");
}
}
Dog.bark();

apply

js中可以指定this的指向,可以把方法写在对象外

1
2
3
4
5
6
7
8
9
10
11
12
function bark() 
{
console.log(this.name + " wang~ wang~");
}

let dog =
{
name: "dog",
bark: bark
}
// 让this指向Dog,传一个空的数组参数(不传也可以)
bark.apply(dog, []);

Date

1
2
3
4
5
let now = new Date();
console.log(now);
console.log(now.getFullYear())
// 注意老外认为Day是星期几
console.log(now.getDay())
  • getMonth 0-11,从0开始

Json

js中也是一切都是对象,任何类型都可以用json无缝转换

  • 对象{}
  • 数组[]
  • 键值对 key:value

JSON也是一个内置类

1
2
3
4
5
6
7
8
9
10
let man = 
{
name: "Peter",
age: 30,
id: "08163442"
}
// 对象转换成json字符串
console.log(JSON.stringify(man));
// 字符串转对象
let new_man = JSON.parse('{"name":"Peter","age":30,"id":"08163442"}');

json是字符串,js中对象是对象类型。

面向对象

原型对象(原型链,是个环)

js里的原型类似java里的类继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"use strict";
let Student = {
id: 1,
name: "student",
age: 18,
study: function () {
console.log(this.name + " is studying!")
}
}

let peter =
{
name: "peter"
}
// 让peter的原型指向Student(类似继承父类)
peter.__proto__ = Student;
peter.study();

这段代码包含了使用严格模式声明的 JavaScript 代码,它定义了一个名为 Student 的对象,以及一个名为 peter 的对象,并将 peter 对象的原型指向 Student 对象。以下是对代码的逐行解释:

  1. 使用严格模式

    1
    "use strict";
    • "use strict"; 是严格模式声明,它告诉 JavaScript 解析器在严格模式下执行代码。在严格模式下,JavaScript 执行会更严格,对一些不安全的或者不规范的代码行为会抛出错误,以提高代码的健壮性和可靠性。
  2. 定义 Student 对象

    1
    2
    3
    4
    5
    6
    7
    8
    let Student = {
    id: 1,
    name: "student",
    age: 18,
    study: function () {
    console.log(this.name + " is studying!")
    }
    };
    • Student 对象包含了 idnameage 三个属性,以及一个 study 方法。
    • study 方法用于打印学生的名字加上 "is studying!" 这样的信息。
  3. 定义 peter 对象

    1
    2
    3
    let peter = {
    name: "peter"
    };
    • peter 对象包含了一个属性 name,其值为 "peter"
  4. 设置原型链

    1
    peter.__proto__ = Student;
    • peter.__proto__ 被设置为 Student 对象。
    • 这意味着 peter 对象的原型链指向了 Student 对象。这样,peter 对象可以继承 Student 对象的属性和方法。
  5. 调用方法

    1
    peter.study();
    • peter.study() 调用了 study 方法。
    • 由于 peter 对象的原型链指向了 Student 对象,因此在调用 study 方法时,this.name 指向了 peter 对象的 name 属性,即 "peter"
    • 所以在控制台中会输出 "peter is studying!"

总结:

  • 通过设置对象的 __proto__ 属性,可以将一个对象的原型指向另一个对象,实现类似继承的效果。
  • 使用严格模式可以提高代码的健壮性和可靠性,因为它会抛出一些不规范的代码行为。

class继承

ES6引入的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Student {
constructor(name) {
this.name = name;
}
study() {
console.log(this.name + " is studying!")
}
}

let peter = new Student("peter");
peter.study();

class BoyStudent extends Student {
constructor(name) {
super(name);
this.gender = "man";
}
}
let jim = new BoyStudent("jim");
jim.study();
console.log(jim.gender)

这段代码展示了使用类(class)和继承(inheritance)的概念来创建对象及其属性和方法。下面是代码的逐行解释:

  1. 定义 Student

    1
    2
    3
    4
    5
    6
    7
    8
    class Student {
    constructor(name) {
    this.name = name;
    }
    study() {
    console.log(this.name + " is studying!");
    }
    }
    • Student 类定义了一个构造函数 constructor 和一个方法 study
    • 构造函数 constructor 接受一个参数 name,并将其赋值给实例的 name 属性。
    • 方法 study 用于打印学生的名字加上 " is studying!" 的信息。
  2. 创建 peter 实例

    1
    2
    let peter = new Student("peter");
    peter.study();
    • 使用 new 关键字创建了一个名为 peterStudent 类的实例,并传入了名字参数 "peter"
    • 调用 peter 实例的 study 方法,输出了 "peter is studying!"
  3. 定义 BoyStudent 类,继承自 Student

    1
    2
    3
    4
    5
    6
    class BoyStudent extends Student {
    constructor(name) {
    super(name);
    this.gender = "man";
    }
    }
    • BoyStudent 类通过 extends 关键字继承自 Student 类。
    • 构造函数中通过 super(name) 调用了父类 Student 的构造函数,以便在 BoyStudent 类中初始化 name 属性。
    • BoyStudent 类新增了一个 gender 属性,其值为 "man"
  4. 创建 jim 实例

    1
    2
    let jim = new BoyStudent("jim");
    jim.study();
    • 使用 new 关键字创建了一个名为 jimBoyStudent 类的实例,并传入了名字参数 "jim"
    • 由于 BoyStudent 类继承自 Student 类,因此 jim 实例也继承了 study 方法。
    • 调用 jim 实例的 study 方法,输出了 "jim is studying!"
  5. 打印 jim 实例的 gender 属性

    1
    console.log(jim.gender);
    • 打印了 jim 实例的 gender 属性,输出了 "man"

总结:

  • 使用类和构造函数可以创建对象模板,并定义对象的属性和方法。
  • 继承可以让一个类(子类)基于另一个类(父类)创建,子类继承了父类的属性和方法,并且可以新增自己的属性和方法。
  • 使用 super() 可以在子类的构造函数中调用父类的构造函数。

操作BOM对象

JavaScript 中的 BOM(Browser Object Model,浏览器对象模型)是一组对象,它们提供了与浏览器窗口交互的方法和属性。以下是一些常见的 BOM 对象及其用途:

  1. Window 对象
    • window 对象表示浏览器中的窗口,它是 BOM 的核心对象之一。
    • 可以使用 window 对象来操作浏览器窗口,比如打开新窗口、关闭窗口、获取窗口大小等。
  2. Document 对象
    • document 对象表示当前加载的文档(网页)。
    • 可以使用 document 对象来操作文档内容,比如获取或修改元素、创建新元素、修改样式等。
  3. Navigator 对象
    • navigator 对象包含有关浏览器的信息,比如浏览器的名称、版本、用户代理等。
    • 可以使用 navigator 对象来根据浏览器的不同采取不同的行为,或者获取浏览器的特性信息。
  4. Location 对象
    • location 对象包含有关当前文档的信息,比如当前文档的 URL。
    • 可以使用 location 对象来获取或修改当前文档的 URL,或者在浏览器中导航到其他页面。
  5. History 对象
    • history 对象包含浏览器的浏览历史记录。
    • 可以使用 history 对象来在浏览历史记录中向前或向后导航,或者获取当前窗口的历史记录状态。
  6. Screen 对象
    • screen 对象包含有关用户屏幕的信息,比如屏幕的大小、颜色深度等。
    • 可以使用 screen 对象来调整页面的布局以适应不同的屏幕尺寸或获取有关用户屏幕的信息。

操作DOM对象

操作 DOM(Document Object Model,文档对象模型)是 JavaScript 中常见的任务之一,它允许你通过 JavaScript 来访问、操作 HTML 文档的结构、内容和样式。以下是一些常见的 JavaScript 操作 DOM 的方法:

  1. 获取元素
    • 使用 document.getElementById(id) 可以通过元素的 id 属性获取对应的元素。
    • 使用 document.querySelector(selector) 可以通过 CSS 选择器获取第一个匹配的元素。
    • 使用 document.querySelectorAll(selector) 可以获取所有匹配的元素。
  2. 操作元素内容
    • 使用 element.innerHTML 属性可以获取或设置元素的 HTML 内容。
    • 使用 element.textContent 属性可以获取或设置元素的文本内容。
    • 使用 element.value 属性可以获取或设置表单元素的值。
  3. 操作元素样式
    • 使用 element.style.property 可以获取或设置元素的内联样式。
    • 使用 element.classList 属性可以操作元素的类名,比如添加、删除、切换类名等。
  4. 操作元素属性
    • 使用 element.getAttribute(name) 可以获取元素指定属性的值。
    • 使用 element.setAttribute(name, value) 可以设置元素指定属性的值。
  5. 创建和添加元素
    • 使用 document.createElement(tagName) 可以创建新的元素节点。
    • 使用 parentNode.appendChild(node) 可以将一个节点添加到指定节点的子节点列表的末尾。
    • 使用 parentNode.insertBefore(newNode, referenceNode) 可以在指定节点的子节点列表中插入一个新的子节点。
  6. 事件处理
    • 使用 element.addEventListener(event, function) 可以向元素添加事件监听器。
    • 使用 element.removeEventListener(event, function) 可以从元素移除事件监听器。

JQuery

jQuery 是一个流行的 JavaScript 库,它简化了 JavaScript 在网页上的操作。它提供了一系列简洁而强大的 API,可以帮助开发者更高效地操作 HTML 元素、处理事件、执行动画等。以下是一些常见的 jQuery 知识点:

  1. 选择器
    • jQuery 提供了强大的选择器功能,可以通过 CSS 选择器来选取元素。例如:$('div') 选取所有 <div> 元素,$('#myId') 选取 id 为 "myId" 的元素。
  2. 操作元素
    • jQuery 提供了丰富的方法来操作选中的元素,比如获取或设置元素的属性、内容和样式,添加或移除元素的类名,以及插入、替换、删除元素等操作。
  3. 事件处理
    • jQuery 提供了便捷的事件处理方法,可以用来绑定事件监听器,响应用户操作。例如:$(element).click(function(){}) 绑定点击事件。
  4. 动画效果
    • jQuery 提供了丰富的动画效果方法,可以用来实现页面元素的动态效果,比如淡入淡出、滑动、展开收起等。例如:$(element).fadeIn() 实现元素的渐显效果。
  5. AJAX
    • jQuery 提供了简化的 AJAX 方法,可以用来发送 HTTP 请求并处理响应。例如:$.ajax({}) 发送 AJAX 请求。
  6. 链式调用
    • jQuery 的方法可以链式调用,使得代码更加简洁和易读。例如:$('div').addClass('highlight').fadeOut() 实现给所有 <div> 元素添加类名 "highlight" 后再渐隐效果。
  7. 插件系统
    • jQuery 有一个庞大的插件生态系统,开发者可以根据需要选择合适的插件来扩展 jQuery 的功能,比如日期选择器、轮播图等。
  8. 跨浏览器兼容性
    • jQuery 解决了不同浏览器之间的兼容性问题,开发者可以放心使用 jQuery 来处理浏览器差异,编写兼容各种浏览器的代码。

当涉及到 jQuery 时,有一些常见的用例。以下是一些代码示例:

  1. 使用 jQuery 选择器选取元素并操作其样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery Example</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
.highlight {
background-color: yellow;
}
</style>
</head>
<body>

<div id="myDiv">Hello, World!</div>

<script>
// 使用 jQuery 选择器选取元素并添加类名
$('#myDiv').addClass('highlight');
</script>

</body>
</html>
  1. <!DOCTYPE html>

    • HTML5 的文档类型声明,告诉浏览器使用 HTML5 规范解析页面。
  2. <html lang="en">

    • HTML 根元素,指定页面的语言为英语。
  3. <head>

    • 包含了页面的元信息,比如字符集、视口设置、标题等。
  4. <meta charset="UTF-8">

    • 设置文档的字符编码为 UTF-8,以支持各种语言的字符集。
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">

    • 设置视口的宽度为设备宽度,并初始化缩放比例为 1.0,以确保页面在移动设备上显示正常。
  6. <title>jQuery Example</title>

    • 设置页面的标题为 "jQuery Example"。
  7. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    • 引入了 jQuery 库,这里使用的是 jQuery 3.6.0 版本的 CDN 地址。
  8. <style>

    • 包含了页面的样式信息。
  9. .highlight { background-color: yellow; }

    • 定义了一个名为 "highlight" 的 CSS 类,设置背景颜色为黄色。
  10. </style>:样式结束标签。

  11. </head>:头部结束标签。

  12. <body>:主体部分开始标签。

  13. <div id="myDiv">Hello, World!</div>

  • 定义了一个 div 元素,id 属性为 "myDiv",内容为 "Hello, World!"。
  1. <script>:脚本开始标签。

  2. $('#myDiv').addClass('highlight');

  • 使用 jQuery 选择器选取了 id 为 "myDiv" 的元素,并添加了 "highlight" 类名,从而应用了预定义的黄色背景样式。
  1. </script>:脚本结束标签。

  2. </body>:主体部分结束标签。

  3. </html>:HTML 结束标签。

  1. 使用 jQuery 处理事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery Example</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

<button id="myButton">Click Me</button>

<script>
// 使用 jQuery 添加点击事件监听器
$('#myButton').click(function() {
alert('Button clicked!');
});
</script>

</body>
</html>
  1. <!DOCTYPE html>

    • HTML5 的文档类型声明,指示浏览器使用 HTML5 规范解析页面。
  2. <html lang="en">

    • HTML 根元素,指定页面的语言为英语。
  3. <head>

    • 包含了页面的元信息,比如字符集、视口设置、标题等。
  4. <meta charset="UTF-8">

    • 设置文档的字符编码为 UTF-8,以支持各种语言的字符集。
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">

    • 设置视口的宽度为设备宽度,并初始化缩放比例为 1.0,以确保页面在移动设备上显示正常。
  6. <title>jQuery Example</title>

    • 设置页面的标题为 "jQuery Example"。
  7. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    • 引入了 jQuery 库,使用的是 jQuery 3.6.0 版本的 CDN 地址。
  8. </head>:头部结束标签。

  9. <body>:主体部分开始标签。

  10. <button id="myButton">Click Me</button>

    • 定义了一个按钮元素,id 属性为 "myButton",显示文本为 "Click Me"。
  11. <script>:脚本开始标签。

  12. $('#myButton').click(function() { alert('Button clicked!'); });

    • 使用 jQuery 选择器选取了 id 为 "myButton" 的按钮元素,并添加了点击事件监听器。
    • 当按钮被点击时,触发匿名函数,弹出一个警告框,显示 "Button clicked!"。
  13. </script>:脚本结束标签。

  14. </body>:主体部分结束标签。

  15. </html>:HTML 结束标签。

  1. 使用 jQuery 实现动画效果
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery Example</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
#myDiv {
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>

<div id="myDiv"></div>

<script>
// 使用 jQuery 实现元素的渐显效果
$('#myDiv').fadeIn('slow');
</script>

</body>
</html>

操作CSS

  1. 获取和设置元素样式
    • 使用 element.style.property 可以获取或设置元素的内联样式。
    • 例如:element.style.backgroundColor = 'red'; 可以将元素的背景颜色设置为红色。
  2. 获取计算样式
    • 使用 window.getComputedStyle(element) 可以获取元素的计算样式。
    • 例如:var computedStyle = window.getComputedStyle(element); 可以获取元素的所有计算样式。
  3. 操作类名
    • 使用 element.classList 属性可以操作元素的类名。
    • 例如:element.classList.add('highlight'); 可以给元素添加名为 "highlight" 的类名。
  4. 操作样式表
    • 可以通过 document.styleSheets 来访问页面的样式表。
    • 可以通过 document.createElement('style') 创建新的 <style> 元素来动态添加样式表。
  5. 获取元素尺寸和位置
    • 使用 element.offsetWidthelement.offsetHeight 可以获取元素的宽度和高度。
    • 使用 element.getBoundingClientRect() 可以获取元素相对于视口的位置和尺寸。
  6. 监听样式变化
    • 可以使用 MutationObserver 来监听元素的样式变化。
    • MutationObserver 是一个 JavaScript API,用于监视 DOM 树的更改。
  7. 获取和设置元素样式
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript操作CSS</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>

<div id="myDiv" class="box">Hello, World!</div>

<script>
// 获取元素并设置其背景颜色为蓝色
var myDiv = document.getElementById('myDiv');
myDiv.style.backgroundColor = 'blue';
</script>

</body>
</html>
  1. 操作类名
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript操作CSS</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
}
.highlight {
background-color: yellow;
}
</style>
</head>
<body>

<div id="myDiv" class="box">Hello, World!</div>

<script>
// 给元素添加类名 "highlight"
var myDiv = document.getElementById('myDiv');
myDiv.classList.add('highlight');
</script>

</body>
</html>
  1. 获取元素尺寸和位置
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript操作CSS</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top: 50px;
left: 50px;
}
</style>
</head>
<body>

<div id="myDiv" class="box">Hello, World!</div>

<script>
// 获取元素的宽度和高度
var myDiv = document.getElementById('myDiv');
console.log('宽度:' + myDiv.offsetWidth + 'px');
console.log('高度:' + myDiv.offsetHeight + 'px');

// 获取元素相对于视口的位置
var rect = myDiv.getBoundingClientRect();
console.log('左上角相对于视口的位置:(' + rect.left + ', ' + rect.top + ')');
</script>

</body>
</html>

一个微型示例:

创建一个简单的小项目,该项目将显示一个待办事项列表,用户可以添加、删除和标记已完成的任务。

HTML 结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To-Do List</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>

<div class="container">
<h1>To-Do List</h1>
<input type="text" id="taskInput" placeholder="Add new task...">
<button onclick="addTask()">Add Task</button>
<ul id="taskList"></ul>
</div>

<script src="script.js"></script>
</body>
</html>

CSS 样式(styles.css):

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
47
48
49
50
51
52
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}

.container {
max-width: 400px;
margin: 50px auto;
padding: 20px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1 {
text-align: center;
color: #333;
}

input[type="text"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
}

button {
display: block;
width: 100%;
padding: 10px;
background-color: #4caf50;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}

ul {
list-style-type: none;
padding: 0;
}

li {
padding: 10px;
margin-bottom: 5px;
background-color: #f9f9f9;
border-radius: 5px;
}

.completed {
text-decoration: line-through;
color: #aaa;
}

JavaScript 代码(script.js):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 获取元素
var taskInput = document.getElementById('taskInput');
var taskList = document.getElementById('taskList');

// 添加任务函数
function addTask() {
var taskText = taskInput.value.trim();
// 获取输入框的值并去除首尾空格

if (taskText !== '') { // 如果输入框不为空
var li = document.createElement('li'); // 创建 li 元素
li.textContent = taskText; // 设置 li 的文本内容为任务内容
li.addEventListener('click', toggleTask); // 添加点击事件监听器,用于标记任务完成
taskList.appendChild(li); // 将 li 添加到任务列表中
taskInput.value = ''; // 清空输入框
}
}

// 标记任务完成函数
function toggleTask() {
this.classList.toggle('completed'); // 切换任务元素的 completed 类
}

这个小项目创建了一个简单的待办事项列表。用户可以在输入框中输入新的任务,然后点击 "Add Task" 按钮将其添加到列表中。每个任务都是一个 li 元素,点击任务可以将其标记为已完成,再次点击可以取消标记。

HTML页面解释:

  1. <!DOCTYPE html>
    • 声明文档类型为 HTML5,告诉浏览器使用 HTML5 规范解析页面。
  2. <html lang="en">
    • HTML 根元素,指定页面的语言为英语。
  3. <head>
    • 包含了页面的元信息,比如字符集、视口设置、标题等。
  4. <meta charset="UTF-8">
    • 设置文档的字符编码为 UTF-8,以支持各种语言的字符集。
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    • 设置视口的宽度为设备宽度,并初始化缩放比例为 1.0,以确保页面在移动设备上显示正常。
  6. <title>To-Do List</title>
    • 设置页面的标题为 "To-Do List",显示在浏览器标签页上。
  7. <link rel="stylesheet" href="styles.css">
    • 引入外部样式表文件 "styles.css",用于设置页面的样式。
  8. <body>
    • 包含了页面的主体内容,用户可见的部分。
  9. <div class="container">...</div>
    • 定义了一个容器 div,类名为 "container",用于包裹页面的主要内容。
  10. <h1>To-Do List</h1>
    • 显示标题 "To-Do List",用于指示该页面是一个待办事项列表。
  11. <input type="text" id="taskInput" placeholder="Add new task...">
    • 输入框,用于用户输入新的待办事项内容,具有 id 为 "taskInput"。
  12. <button onclick="addTask()">Add Task</button>
    • 按钮,用于触发添加任务的操作,点击后调用 JavaScript 函数 "addTask()"。
  13. <ul id="taskList"></ul>
    • 无序列表,用于显示待办事项列表,具有 id 为 "taskList"。
  14. <script src="script.js"></script>
    • 引入外部 JavaScript 文件 "script.js",用于编写处理待办事项逻辑的 JavaScript 代码。

CSS页面解释:

  1. body
    • 设置页面的整体样式,包括字体和背景颜色。
  2. .container
    • 定义了一个类名为 "container" 的样式,用于包裹待办事项列表应用的主要内容。
    • max-width 属性限制容器的最大宽度为 400px。
    • margin 属性设置容器的外边距,使其在页面垂直方向上居中。
    • padding 属性设置容器的内边距,增加内容与容器边缘的间距。
    • background-color 属性设置容器的背景颜色为白色。
    • border-radius 属性设置容器的边框圆角。
    • box-shadow 属性创建容器的阴影效果。
  3. h1
    • 标题样式,设置文字居中显示和颜色为深灰色。
  4. input[type="text"]
    • 输入框样式,设置宽度为100%、内边距和外边距,以及底部外边距。
  5. button
    • 按钮样式,设置宽度为100%、内边距、背景颜色、文字颜色、边框、边框圆角和光标样式。
  6. ul
    • 无序列表样式,将列表项的标记类型设置为无,去除默认的列表标记样式。
  7. li
    • 列表项样式,设置内边距、底部外边距、背景颜色和边框圆角。
  8. .completed
    • 用于标记已完成任务的样式,设置文本装饰为删除线和颜色为灰色。

JavaScript解释:

  1. 获取元素
    • 使用 document.getElementById('taskInput')document.getElementById('taskList') 获取了页面中 id 分别为 "taskInput" 和 "taskList" 的两个元素,分别表示输入框和任务列表。
  2. 添加任务函数 (addTask):
    • 当用户输入新的任务并点击 "Add Task" 按钮时,该函数将被调用。
    • 使用 taskInput.value.trim() 获取输入框的值,并通过 trim() 方法去除首尾空格,保存到变量 taskText 中。
    • 使用 if (taskText !== '') 条件判断,确保输入框不为空。
    • 如果输入框不为空,就创建一个新的列表项 (<li>) 元素,设置其文本内容为用户输入的任务内容 (taskText)。
    • 使用 addEventListener() 方法给新创建的列表项添加了一个点击事件监听器,当用户点击列表项时,将触发 toggleTask 函数,用于标记任务完成。
    • 最后将新创建的列表项添加到任务列表 (taskList) 中,并清空输入框的值,以便用户输入下一个任务。
  3. 标记任务完成函数 (toggleTask):
    • 当用户点击任务列表中的某个任务时,该函数将被调用。
    • 使用 this.classList.toggle('completed') 切换当前被点击的任务元素 (<li>) 的样式类名。如果任务元素已经有了 completed 类名,则移除它;如果没有,则添加它。
    • 样式类名 completed 是用来标记已完成的任务,添加该类名后,任务内容将显示为删除线,颜色也会变为灰色。

参考对象:

https://bxs.ink/front-end/js.html#%E6%93%8D%E4%BD%9Cdom%E5%AF%B9%E8%B1%A1

https://www.kuangstudy.com/bbs/1352542033306263553

https://www.w3cschool.cn/umsno/umsno-n1yz25w8.html