欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > 零基础学前端-传统前端开发(第四期-JS基础)

零基础学前端-传统前端开发(第四期-JS基础)

2025/6/21 22:11:14 来源:https://blog.csdn.net/2404_89737060/article/details/148798888  浏览:    关键词:零基础学前端-传统前端开发(第四期-JS基础)

经过前面学过的HTML,CSS的学习,相信大家已经可以使用进行常用的页面开发,接下来我们就要学习JavaScript,鉴于内容过多,需要长期练习

流程为:数据类型>>运算>>语法,语句>>对象>>数组>>函数>>类

软件使用:谷歌浏览器(当然如果你了解的话可以用nodejs试一下,但是为了方便,本系列都是用的浏览器)

JavaScript相比起HTML,CSS是有一定难度的,可以作为一门编程语言而学的,但是学会

JavaScript对于后期我们学习nodejs(包括python爬虫的学习)的时候帮助很大,所以仍然要细心学习

JavaScript在前端开发有什么用呢:

在开发房子中HTML相当于房子水泥钢筋铸的结构骨架,CSS相当于房子的装修风格,而JavaScript相当于智能家居一样,可以让网站变得动态(也就是我们看到的动画效果)

学习JavaScript之前,我们先学数据类型,这个东西有过学习其他开发语言的朋友应该了解

数据类型

一、基本数据类型(Primitive Data Types)

基本数据类型是构成 JavaScript 最基础的单位,存储在栈内存中,直接存储实际的数据值。JavaScript 的基本数据类型包括以下几种:

String(字符串):用来表示文本数据,可以是一个字符或一串字符序列,例如"Hello"、'JavaScript'、"42"等。字符串是不可变的,每次对字符串的操作都会产生新的字符串实例。

Number(数字):表示数字,包括整数和浮点数。例如42、3.14、-7等。JavaScript 中的数字没有区分整型和浮点型,统一用 Number 表示。

Boolean(布尔值) :表示逻辑实体,只有两个值:true 和 false。通常用于条件判断中。(在之前的皮卡丘靶场中的布尔类型的内容中我们短暂的了解过)

Undefined(未定义):表示变量未被赋值,或者尚未声明的变量的默认值。例如:let x;,此时 x 的值就是 undefined。

Null(空值):表示没有值,或者对象为空。null 是一个空对象引用。它和 undefined 常常容易混淆,但它们表示的意义不同。

二、引用数据类型(Reference Data Types)

引用数据类型是复合数据类型,通常存储在堆内存中,变量存储的是对象在内存中的地址(引用)。以下是常见的引用数据类型:

Object(对象):是 JavaScript 中最通用的引用数据类型,以键值对的形式存储数据。例如:let person = { name: 'John', age: 30 }。

Array(数组):是一种特殊的对象,用于存储多个值,这些值可以通过索引来访问。例如:let arr = [1, 2, 3, 'JavaScript']。

Function(函数):在 JavaScript 中,函数其实也是一种特殊的对象,可以被赋值、传递和返回。例如:function add(a, b) { return a + b; } 或者箭头函数:const add = (a, b) => a + b;。

以上是数据类型的知识,虽然看起来很简单,但是在开发语言中,这是非常重要的地基,如果没有记牢的话会影响后面的学习

运算

接下来我们学习运算(类似于你学习数学,你得先知道各类数字比如:整数,有小数点的,有分号的,今天的运算相当于了解加减乘除的符号用法)

直接用谷歌浏览器来运行即可:我们按压F12打开console(如果你汉化过叫"控制台")在里面输入即可

一,算数运算符

作用:执行基本的数学运算

+ 加法

- 减法

* 乘法

/ 除法

% 求余

示例

let a = 5;let b = 3;console.log(a + b); // 8console.log(a - b); // 2console.log(a * b); // 15console.log(a / b); // 1.666...console.log(a % b); // 2

类似以上内容,直接把内容放到控制台运行即可

二,比较运算符

作用:比较运算符用于比较两个值,返回布尔值(true 或 false

== 等于

!= 不等于

> 大于

< 小于

>= 大于等于

<= 小于等于

示例

let a = 5;let b = 3;console.log(a == b); // falseconsole.log(a != b); // tureconsole.log(a > b); // trueconsole.log(a <= b); // false

三,逻辑运算符

作用:逻辑运算符用于组合布尔值,返回布尔结果。

&& 逻辑与(AND)

|| 逻辑或(OR)

! 逻辑非(NOT)

示例

let a = 5;let b = 3;console.log(a > 2 && b < 4); // trueconsole.log(a < 2 || b > 4); // falseconsole.log(!(a == b)); // true

四,赋值运算符

作用:赋值运算符用于给变量赋值

= 简单赋值

+= 加法赋值

-= 减法赋值

*= 乘法赋值

/= 除法赋值

%= 取模赋值

示例

let c = 10;c += 5; // c = 15c -= 3; // c = 12c *= 2; // c = 24c /= 4; // c = 6c %= 5; // c = 1console.log(c); // 1

由此我们还可以知道JavaScript读取时显示的的是最后一个结果,是因为每次运算的结果会覆盖之前的值,或者你只在最后调用了输出函数

语法语句

接下来是语法,语句

传统的语法定义:音义结合的各结构单位之间的组织规则的汇集。但是在JavaScript学习中,语法意为描述合法代码书写规则的集合(就是拼拼图,必须按照固定搭配才能拼好)

语句:是程序中执行一个操作的基本单元,它是构成程序的基本结构元素之一(就好像写作文,是一句话一句话拼起来的)

语法:

代码块:

代码块是用花括号 {}括起来的代码片段,通常用于表示代码的逻辑结构。

比如在if语句、for循环、while循环和函数中,代码块用来定义执行的具体操作。(在 JavaScript 中,语句通常以分号(;)结尾,表示一个完整的操作结束。)

if (age >= 18) {console.log("成年了");console.log("可以参加选举了");}这里的 {} 中的内容就是代码块,表示当条件满足时,要执行的多个操作。

注释:

注释是用来解释代码片段的,它不会被浏览器执行,但可以帮助我们理解代码的逻辑。(类似于你背英语单词,考试的时候不会看你了不了解,只看你写出来的回答这就是浏览器执行的内容,你背在脑子里的翻译语法就是注释)

单行注释

使用 //,它只能注释这一行的内容

// 这是单行注释,解释变量的作用let x = 10; // 初始化变量 x
多行注释

使用 /* 和 */ 包裹内容,可以注释多行代码。

/*这是一个多行注释,可以用来解释一个复杂的功能模块或者代码逻辑*/

语句:

变量声明

var语句:是 JavaScript 中最初用于声明变量的关键字。它具有函数作用域,也就是说在函数内部用 var 声明的变量,只在该函数内部有效。

function test() {var x = 10;}console.log(x); // 会报错,因为 x 只在 test 函数内部有效

let语句:用于声明变量的关键字,它具有块级作用域。块级作用域是指在一对大括号({})内声明的变量,只在该大括号内有效。

{let y = 20;}console.log(y); // 会报错,因为 y 只在大括号内有效

const:const 用于声明常量,也具有块级作用域。一旦声明后,常量的值不能被改变。

const PI = 3.14;console.log(PI); // 输出 3.14PI = 3; // 会报错,不能修改常量的值

条件语句

(类似于如果...我就..这种说法内容)

if 语句:if 语句用于根据条件执行不同的代码。

语法格式

if (条件) {代码块}
var age = 18;if(age >= 18){console.log("你好");}

if...else 语句:当需要在条件为真和为假时分别执行不同的代码时,可以使用 if...else 语句。

语法格式

if (条件) {代码块 1} else {代码块 2}
var score = 60;if(score >= 60){console.log("及格");}else{console.log("不及格");}如果 `score >= 60` 为真,就执行代码块 1 ,输出 “及格”;否则执行代码块 2 ,输出 “不及格”。

if...else if...else 语句:当有多个条件需要判断时,可以使用 if...else if...else 语句。

语法格式

if (条件 1) {代码块 1} else if (条件 2) {代码块 2} else {代码块 3}
var num = 5;if(num > 10){console.log("大于 10");}else if(num > 5){console.log("大于 5");}else{console.log("小于等于 5");}

循环语句

for 循环:for 循环用于重复执行一段代码,直到满足特定条件为止。

语法格式

for (初始化表达式; 条件表达式; 更新表达式) {代码块}* 解释:* 初始化表达式:通常用于初始化循环变量。* 条件表达式:在每次循环开始前进行判断,如果为真,则执行循环体;如果为假,则退出循环。* 更新表达式:在每次循环体执行完毕后更新循环变量。* 例如:for(let i = 0; i < 3; i++){console.log(i); // 输出 0、1、2}这里初始化变量 `i` 为 0 ,条件是 `i < 3` ,每次循环后 `i` 增加 1 。循环会执行 3 次,依次输出 0、1、2。

while 循环:while 循环也是用于重复执行一段代码,

while (条件) {代码块}* 先判断条件是否为真,如果为真,就执行代码块,然后再次判断条件,直到条件为假。* 例如:let count = 0;while(count < 3){console.log(count); // 输出 0、1、2count++;}如果不注意在循环体中更新变量(如这里的 `count++` ),可能会导致死循环,因为条件一直为真。

do...while 循环do...while 循环和 while 循环类似,但它的区别在于不管条件是否为真,都会先执行一次代码块,然后再判断条件

语法格式

do {代码块} while (条件);
{let num = 1; // 这个 num 只在这个花括号的作用域内有效do {console.log(num); // 输出 num 的值num++; // num 值加 1} while (num <= 5); // 只要 num 小于等于 5,就继续循环}

循环语句区别

条件判断时机

for 循环:在每次循环开始前都会先执行条件表达式的判断。

while 循环:同样在每次循环开始前判断条件,但没有内置的初始化和更新表达式。

初始化和更新

for 循环:将初始化、条件判断和更新操作集中在一个语句中,结构更紧凑,适合有明确的初始化和更新逻辑的场景。

while 循环:没有内置的初始化和更新操作,需要在循环体内部手动处理。

执行条件

do...while 循环do...while 循环会先执行一次循环体,然后才判断条件。因此,它至少会执行一次循环体,即使条件一开始就不满足。

for 和 while 循环:如果条件一开始就不满足,循环体可能一次都不执行。

适用点

for 循环

适用场景:当你需要在循环中初始化一个变量,并且每次循环后需要更新这个变量时,for 循环是一个很好的选择。它将初始化、条件判断和更新操作集中在一个地方,代码更清晰。

示例

遍历数组或集合。

执行固定次数的循环。

for (let i = 0; i < 5; i++) {console.log(i); // 输出 0, 1, 2, 3, 4}

while 循环

适用场景:当你需要在循环中动态地控制条件,或者循环的次数不确定时,while 循环更适合。它更灵活,因为你可以根据需要在循环体中动态地改变条件变量。

示例

读取用户输入,直到用户输入特定的值。

执行一个任务,直到某个条件满足。

let num = 0;while (num < 5) {console.log(num); // 输出 0, 1, 2, 3, 4num++;}

for 循环:适合有明确的初始化和更新逻辑,循环次数相对确定的场景。

while 循环:适合循环次数不确定,或者需要在循环体中动态控制条件的场景。

break 语句

break 语句用于完全终止当前的循环,跳出循环体,继续执行循环之后的代码。

当你需要在满足某个条件时立即退出循环时,可以使用 break

常用于避免无限循环或在找到目标后提前退出循环。

const numbers = [1, 3, 5, 12, 8, 15];for (let i = 0; i < numbers.length; i++) {if (numbers[i] > 10) {console.log("找到第一个大于 10 的数字:", numbers[i]);break; // 找到后立即退出循环}}console.log("循环结束");

continue 语句

continue 语句用于跳过当前循环的剩余部分,直接开始下一次循环迭代。

    当你需要跳过某些特定条件的迭代,但仍然继续执行后续的迭代时,可以使用 continue

    常用于过滤掉不符合条件的元素,只处理符合条件的元素。

    const numbers = [1, 2, 3, 4, 5, 6];for (let i = 0; i < numbers.length; i++) {if (numbers[i] % 2 !== 0) {continue; // 如果是奇数,跳过当前迭代}console.log("偶数:", numbers[i]);}

    break 和 continue 的区别

    break

    完全终止循环,跳出循环体,继续执行循环之后的代码。

    用于提前退出循环。

    continue

    跳过当前迭代的剩余部分,直接开始下一次迭代。

    用于跳过某些特定条件的迭代,但仍然继续执行后续的迭代。

    至此,语法语句内容完成

    对象

    接下来,来接触一下对象

    首先:此对象非彼对象,学校里面学好了说不定有对象

    什么是编程中的对象呢:在 JavaScript 中,对象是一个独立的、可以存储多个值的实体,它由一系列的键值对(key-value pairs)组成。键(key)是对象的属性名称,值(value)可以是任何数据类型,包括数字、字符串、布尔值、函数(方法)等。你可以把对象想象成一个装满各种信息的“盒子”。

    例如,一个描述人的对象:

    let person = {name: "张三",age: 25,isStudent: true,hobbies: ["阅读", "运动"],greet: function() {console.log("你好,我叫" + this.name);}};// 调用 greet 方法person.greet();

    在这个对象中:

    nameageisStudent 是属性,它们的值分别是 "张三"25true

    hobbies 是一个数组类型的属性,它的值是包含两个字符串的数组。

    greet 是一个方法(即对象中的函数,在下一篇会详细介绍函数的),它可以输出 "你好,我叫张三"

    创建对象

    方法:对象字面量

    最常见的方式是使用对象字面量来创建对象,就像上面示例中的 person 对象。这种方式简单直观,适合直接定义对象的属性和方法。

    语法:

    let 对象名 = {属性1: 值1,属性2: 值2,// ...};

    访问对象的属性和方法

    方法1:点语法

    console.log(person.name); // 访问属性person.greet(); // 调用方法

    方法2:方括号语法

    console.log(person["name"]);person["greet"]();

    添加、修改和删除属性

    添加属性
    person.gender = "男"; // 添加属性
    修改属性
    person.age = 26; // 修改属性
    删除属性
    delete person.age; // 删除属性

    对象的遍历

    (遍历在之前的文章中讲过,就是一个盒子里有很多小球然后一个一个拿出来)

    可以使用 for...in 循环来遍历对象的属性:

    for (let key in person) {console.log(key + ": " + person[key]);}

    可能听的云里雾里的,之后会有一篇关于传统前端实战的分析文章

    数组

    接下来我们来了解数组

    什么是数组:数组是一种非常常用的数据结构,用于存储一组有序的值。这些值可以是数字、字符串、对象,甚至是其他数组。数组中的每个值都有一个索引(从 0 开始),可以通过索引来访问和操作数组中的元素。

    (类似于我们学过的数学里的集合,但只是表现上类似而已)

    创建数组

    方法 :数组字面量

    这是最常用的方式,直接用方括号 [] 包裹一组值。

    let fruits = ["苹果", "香蕉", "橙子"];let numbers = [1, 2, 3, 4, 5];let mixed = [1, "hello", true, { name: "张三" }, [1, 2, 3]];

    访问数组元素

    数组中的每个元素都有一个索引,从 0 开始。可以通过索引来访问和修改数组中的元素。

    let fruits = ["苹果", "香蕉", "橙子"];// 访问元素console.log(fruits[0]); // 输出 "苹果"console.log(fruits[1]); // 输出 "香蕉"// 修改元素fruits[1] = "草莓";console.log(fruits); // 输出 ["苹果", "草莓", "橙子"]

    数组的常用方法

    添加和删除元素

    push():向数组末尾添加一个或多个元素,并返回新数组的长度。

    fruits.push("葡萄");console.log(fruits); // 输出 ["苹果", "草莓", "橙子", "葡萄"]

    pop():从数组末尾移除一个元素,并返回被移除的元素。

    let removedItem = fruits.pop();console.log(removedItem); // 输出 "葡萄"console.log(fruits); // 输出 ["苹果", "草莓", "橙子"]

    shift():从数组开头移除一个元素,并返回被移除的元素。

    let firstItem = fruits.shift();console.log(firstItem); // 输出 "苹果"console.log(fruits); // 输出 ["草莓", "橙子"]

    unshift():向数组开头添加一个或多个元素,并返回新数组的长度。

    fruits.unshift("樱桃");console.log(fruits); // 输出 ["樱桃", "草莓", "橙子"]
    查找元素

    indexOf():查找某个值在数组中的索引,如果找不到返回 -1

    let index = fruits.indexOf("橙子");console.log(index); // 输出 2

    (因为计数的时候第一个数字记为0,也就是说你觉的苹果应该是1但他的序号实际为0)

    includes():检查数组是否包含某个值,返回布尔值。

    console.log(fruits.includes("草莓")); // 输出 trueconsole.log(fruits.includes("西瓜")); // 输出 false
    遍历数组

    for 循环

    for (let i = 0; i < fruits.length; i++) {console.log(fruits[i]);}
    数组的拷贝和拼接

    slice():返回数组的一个浅拷贝,不会修改原数组。

    let newFruits = fruits.slice(1, 3); // 从索引 1 到 3(不包括 3)console.log(newFruits); // 输出 ["草莓", "橙子"]

    concat():将多个数组拼接成一个新数组,不会修改原数组。

    let moreFruits = ["西瓜", "芒果"];let allFruits = fruits.concat(moreFruits);console.log(allFruits); // 输出 ["樱桃", "草莓", "橙子", "西瓜", "芒果"]
    数组的排序

    sort():对数组进行排序,会修改原数组。

    let numbers = [3, 1, 4, 1, 5, 9];numbers.sort();console.log(numbers); // 输出 [1, 1, 3, 4, 5, 9]

    如果需要按照数值大小排序,需要提供一个比较函数:

    numbers.sort(function(a, b) {return a - b; // 升序});console.log(numbers); // 输出 [1, 1, 3, 4, 5, 9]
    数组的过滤和映射

    filter():创建一个新数组,包含通过测试的所有元素,不会修改原数组。

    let evenNumbers = numbers.filter(function(num) {return num % 2 === 0;});console.log(evenNumbers); // 输出 [4]

    map():创建一个新数组,其元素是调用一次提供的函数后的返回值,不会修改原数组。

    let squaredNumbers = numbers.map(function(num) {return num * num;});console.log(squaredNumbers); // 输出 [1, 1, 9, 16, 25, 81]

    由于没有足够的实际生活应用,所以大家可能会觉得很莫名其妙,但是现在只要了解基础理论就行了,后面会有实践内容的

    函数

    在数学中函数的概念就像机器人一样,通过特定的指令做出特定的动作,在JavaScript开发中概念也差不多

    函数的定义

    函数是代码块,用于执行特定行为。在 JavaScript 中,可以通过多种方式定义函数。

    函数声明:

    以 function 关键字开头,后面跟着函数名、参数列表(括在圆括号中,用逗号分隔)和函数体(用大括号括起来)。

    function functionName (parameter1, parameter2, ...) {// 函数体,执行的代码// 可以使用 return 语句返回值}

    我们来分析一个例子

    function addNumbers (num1, num2) {let sum = num1 + num2;return sum;}这里定义了一个名为 addNumbers 的函数,它接收两个参数 num1 和 num2,将它们相加并将结果存储在变量 sum 中然后通过 return 语句返回这个结果。

    函数表达式:

    它将函数赋值给一个变量。可以是匿名函数或者有名字的函数

    const functionName = function (parameter1, parameter2, ...) {// 函数体};

    比如

    const multiplyNumbers = function (num1, num2) {return num1 * num2;};

    或者

    const divideNumbers = function division (num1, num2) {return num1 / num2;};

    这样做的好处是函数可以作为一个值来传递,比如在事件处理等场景中非常有用。

    函数的调用

    调用函数时,使用函数名后跟一对圆括号,括号中包含实际参数(实参)。

    let result = addNumbers (5, 3);console.log (result); // 输出 8

    这里调用了之前定义的 addNumbers 函数,传入了实际参数 5 和 3,函数执行后返回它们的和 8,然后将这个结果赋值给变量 result

    函数的参数

    默认参数 :在定义函数时,可以给参数指定默认值。如果调用函数时没有提供对应的参数,就会使用默认值。

    function greet (name = "Guest") {console.log (`Hello, ${name}!`);}greet (); // 输出 "Hello, Guest!"greet ("Alice"); // 输出 "Hello, Alice!"

    参数的类型检查 :在 JavaScript 中,参数的类型是动态的。可以在函数内部使用 typeof 运算符来检查参数类型

    function checkType (value) {console.log (`The type of the parameter is: ${typeof value}`);}checkType (123); // 输出 "The type of the parameter is: number"checkType ("Hello"); // 输出 "The type of the parameter is: string"

    函数的返回值使用 return 语句可以将值返回给调用者。如果函数中没有 return 语句,或者 return 后面没有值,返回值是 undefined。

    function sayHello () {console.log ("Hello!");}let result = sayHello ();console.log (result); // 输出 undefined

    这个函数只是输出了 "Hello!",没有返回任何值,所以 result 的值是 undefined

    函数的作用域

    函数作用域 :在函数内部声明的变量只能在函数内部访问,这是函数作用域。而变量的声明方式会影响其作用域。

    function createVariable () {var functionScopedVar = "I'm function - scoped";console.log (functionScopedVar);}createVariable (); // 正常输出// console.log (functionScopedVar); // 会报错,因为变量只在函数内部

    高阶函数

    函数可以作为参数传递给其他函数。

    function execute (func, value) {return func (value);}function double (num) {return num * 2;}let result = execute (double, 5);console.log (result); // 输出 10

    这里 execute 是一个高阶函数,它接收一个函数 func 和一个值 value 作为参数,然后调用 func 函数并将 value 传递给它。

    函数可以作为返回值从其他函数返回。

    function createMultiplier (multiplier) {return function (num) {return num * multiplier;};}let triple = createMultiplier (3);console.log (triple (5)); // 输出 15

    闭包

    闭包是一个函数及其词法环境的组合。它可以访问其词法作用域中的变量。

    function createCounter () {let count = 0;return function () {count++;return count;};}let counter = createCounter ();console.log (counter ()); // 输出 1console.log (counter ()); // 输出 2

    这里 createCounter 函数返回了一个闭包函数。闭包函数可以访问 createCounter 函数中的变量 count,并能够修改它。每次调用闭包函数时,count 的值都会增加并返回新的值。

    递归函数

    递归函数是指在函数内部调用自身的函数。

    function factorial (n) {if (n === 0) {return 1;} else {return n * factorial (n - 1);}}console.log (factorial (5)); // 输出 120

    这个 factorial 函数计算了 5 的阶乘。它不断调用自身,每次将参数减 1,直到参数为 0 时返回 1,然后逐层返回计算结果。

    立即调用函数表达式(IIFE)

    它是一种定义并立即执行的函数模式,用于创建一个封闭的作用域,避免污染全局作用域。

    (function () {let privateVariable = "I'm private";console.log (privateVariable);})();// console.log (privateVariable); // 会报错,变量在 IIFE 内部

    这个函数定义后立即执行,privateVariable 在 IIFE 内部被声明和使用,外部无法访问它。

    类的基本定义

    使用 class 关键字定义一个类,类名首字母通常大写,以区分于其他变量名。

    class MyClass {// 类体}

    示例:定义一个简单的 “Person” 类,用于表示一个人。

    class Person {// 类体暂时为空}

    构造函数

    构造函数是一个特殊的方法,用于初始化对象的属性。它使用 constructor 关键字定义。

    当使用 new 关键字创建类的实例时,构造函数会被自动调用。

    示例:在 “Person” 类中添加构造函数,用于初始化人的姓名和年龄。

    class Person {constructor(name, age) {this.name = name; // 将传入的 name 参数赋值给对象的 name 属性this.age = age; // 将传入的 age 参数赋值给对象的 age 属性}}// 创建 Person 类的实例const person1 = new Person('Alice', 25);console.log(person1.name); // 输出:Aliceconsole.log(person1.age); // 输出:25

    类的方法

    在类中定义的方法是对象的行为,用于实现对象的功能。

    方法的定义方式与普通函数类似,但要写在类的内部。

    示例:在 “Person” 类中添加一个方法,用于打印个人信息。

    class Person {constructor(name, age) {this.name = name;this.age = age;}// 定义一个方法introduce() {console.log(`My name is ${this.name}, I am ${this.age} years old.`);}}const person1 = new Person('Alice', 25);person1.introduce(); // 输出:My name is Alice, I am 25 years old.

    类的继承

    通过继承,一个类可以继承另一个类的属性和方法,从而实现代码的复用。

    使用 extends 关键字实现继承,子类通过 super() 关键字调用父类的构造函数。

    示例:创建一个 “Student” 类,它继承自 “Person” 类,用于表示学生。

    class Person {constructor(name, age) {this.name = name;this.age = age;}introduce() {console.log(`My name is ${this.name}, I am ${this.age} years old.`);}}// Student 类继承 Person 类class Student extends Person {constructor(name, age, grade) {super(name, age); // 调用父类的构造函数,初始化 name 和 agethis.grade = grade; // 子类独有的属性}// 子类自己的方法study() {console.log(`I am a student in grade ${this.grade}.`);}}const student1 = new Student('Bob', 18, '10th');student1.introduce(); // 继承自父类的方法student1.study(); // 子类自己的方法

    静态方法和属性

    静态方法和属性属于类本身,而不是类的实例。使用 static 关键字定义。

    静态方法通过类名直接调用,静态属性也通过类名访问。

    示例:在 “Person” 类中添加一个静态方法和一个静态属性。

    class Person {constructor(name, age) {this.name = name;this.age = age;}introduce() {console.log(`My name is ${this.name}, I am ${this.age} years old.`);}// 静态方法static sayHello() {console.log('Hello, everyone!');}// 静态属性static species = 'Homo sapiens';}Person.sayHello(); // 调用静态方法console.log(Person.species); // 访问静态属性

    访问修饰符

    在 JavaScript 中,类的属性和方法默认都是公开的(public),即可以在类的外部访问。

    也可以使用 # 来定义私有属性和方法,它们只能在类的内部访问。

    示例:在 “Person” 类中添加一个私有属性和一个私有方法。

    class Person {constructor(name, age) {this.name = name;this.age = age;this.#privateData = 'This is private data'; // 私有属性}introduce() {console.log(`My name is ${this.name}, I am ${this.age} years old.`);this.#privateMethod(); // 调用私有方法}// 私有方法#privateMethod() {console.log(this.#privateData);}}const person1 = new Person('Alice', 25);person1.introduce();// 以下代码会报错,因为无法在类外部访问私有属性和方法// console.log(person1.#privateData);// person1.#privateMethod();

    接下来我们整合内容,分析一个全面的实例

    示例

    目标

    创建一个简单的图书管理系统,包含以下功能:

    定义图书类(Book),包含书名、作者和页数。

    定义图书馆类(Library),可以添加图书、列出所有图书、借阅图书和归还图书。

    使用数组存储图书数据。

    使用函数实现图书的借阅和归还逻辑。

    使用类的继承扩展功能。

    // 数据类型// 基本数据类型:String, Number, Boolean, Undefined, Null// 复合数据类型:Object, Array// 运算// 算术运算符:+、-、*、/、%// 比较运算符:==、===、!=、!==、>、<、>=、<=// 逻辑运算符:&&、||、!// 语法语句// if...else、for、while、switch// 对象// 使用对象表示图书const book1 = {title: 'JavaScript高级程序设计',author: 'Nicholas C. Zakas',pages: 600,isAvailable: true};const book2 = {title: '你不知道的JavaScript',author: 'Kyle Simpson',pages: 300,isAvailable: true};// 数组// 使用数组存储图书const books = [book1, book2];// 函数// 借阅图书的函数function borrowBook(book) {if (book.isAvailable) {book.isAvailable = false;console.log(`您已成功借阅《${book.title}》。`);} else {console.log(`《${book.title}》当前不可借阅。`);}}// 归还图书的函数function returnBook(book) {book.isAvailable = true;console.log(`您已成功归还《${book.title}》。`);}// 类// 定义图书类class Book {constructor(title, author, pages) {this.title = title;this.author = author;this.pages = pages;this.isAvailable = true;}}// 定义图书馆类class Library {constructor() {this.books [];=  }// 添加图书addBook(book) {this.books.push(book);console.log(`图书《${book.title}》已添加到图书馆。`);}// 列出所有图书listBooks() {console.log('图书馆中的图书:');this.books.forEach(book => {console.log(`- ${book.title}(作者:${book.author},页数:${book.pages},状态:${.isbookAvailable ? '可借阅' : '已借出'})`);});}// 借阅图书borrowBook(title) {const book = this.books.find(book => book.title === title);if (book) {if (book.isAvailable) {book.isAvailable = false;console.log(`您已成功借阅《${book.title}》。`);} else {console.log(`《${book.title}》当前不可借阅。`);}} else {console.log(`图书馆中没有找到《${title}》。`);}}// 归还图书returnBook(title) {const book = this.books.find(book => book.title === title);if (book) {book.isAvailable = true;console.log(`您已成功归还《${book.title}》。`);} else {console.log(`图书馆中没有找到《${title}》。`);}}}// 类的继承// 定义一个特殊图书馆类,继承自 Libraryclass SpecialLibrary extends Library {constructor() {super();this.specialBooks = [];}// 添加特殊图书addSpecialBook(book) {this.specialBooks.push(book);console.log(`特殊图书《${book.title}》已添加到特殊图书馆。`);}// 列出特殊图书listSpecialBooks() {console.log('特殊图书馆中的特殊图书:');this.specialBooks.forEach(book => {console.log(`- ${book.title}(作者:${book.author},页数:${book.pages},状态:${book.isAvailable ? '可借阅' : '已借出'})`);});}}// 测试代码// 创建图书馆实例const myLibrary = new Library();// 创建图书实例const book3 = new Book('JavaScript权威指南', 'David Flanagan', 1200);const book4 = new Book('深入理解计算机系统', 'Randal E. Bryant', 1000);// 添加图书到图书馆myLibrary.addBook(book3);myLibrary.addBook(book4);// 列出所有图书myLibrary.listBooks();// 借阅图书myLibrary.borrowBook('JavaScript权威指南');myLibrary.listBooks();// 归还图书myLibrary.returnBook('JavaScript权威指南');myLibrary.listBooks();// 创建特殊图书馆实例const specialLibrary = new SpecialLibrary();// 添加特殊图书specialLibrary.addSpecialBook(book1);specialLibrary.addSpecialBook(book2);// 列出特殊图书specialLibrary.listSpecialBooks();

    数据类型:使用了基本数据类型(如字符串、数字、布尔值)和复合数据类型(对象、数组)。

    运算:在判断图书是否可借阅时使用了比较运算符和逻辑运算符。

    语法语句:使用了 if...elseforwhile 等语句。

    对象:通过对象表示图书,包含书名、作者、页数和是否可借阅的状态。

    数组:使用数组存储图书数据,方便管理和遍历。

    函数:定义了借阅和归还图书的函数,封装了逻辑。

    :定义了 Book 类表示图书,Library 类表示图书馆,SpecialLibrary 类继承自 Library 类,扩展了功能。

    至此,JavaScript完成,传统前端开发也完成了

    版权声明:

    本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

    我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

    热搜词