【鸿蒙系统学习笔记】TypeScript开发语言

一、背景

HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScript 本身也是由另一门语言 JavaScript 扩展而来。因此三者的关系如下图所示

二、TypeScript

2.1、运行环境

2.1.1、线上Playground

TypeScript提供了一个线上的 Playground 供练习使用,地址为TypeScript: 演练场 - 一个用于 TypeScript 和 JavaScript 的在线编辑器。

2.1.2、本地运行环境 

2.1.2.1、采用的是VSCode 编辑器
2.1.2.2、前提条件

1、安装插件:Code Runner:它提供了简便的代码执行功能,支持多种编程语言,使开发者能够快速运行和调试代码片段。


2、安装Node.js并配置Path环境变量

说明:我已经安装了Node.js,便不重复安装了

为了方便在终端执行Node.js相关的命令,我们需要将Node.js的安装目录加入到Path环境变量下

步骤1:首先在DevEco Studio的设置界面查看Node.js的安装目录

步骤2:然后打开环境变量配置面板,按下 Win+,唤起运行窗口,之后运行命令 sysdm.cpl 

步骤3:点击高级选项卡,并点击环境变量

步骤4:在系统变量中选中 Path ,并点击编辑

步骤5:点击新建,并填入Node.js的安装目录,完成后点击确定


3、安装ts-node

这是一个 TypeScript 的运行环境,它允许我们直接运行 TypeScript 代码。ts-node的安装和运行依赖于Node.js环境,已经安装了Node.js

npm install -g ts-node

在终端中输入node -v 和ts-node -v后出现各自版本,说明这两个已经安装成功了,如下:

注:完成后需要重新启动VSCode,另其重新加载环境变量和相关依赖。

2.1.2.3、编写程序并运行

首先在合适的位置创建一个工程目录,例如C:\Users\......\hello-ts,然后使用VSCode打开目录,创建ts文件,并编写Typescript代码运行

问题:运行ts时出现以下错误,百度后发现是由于 ts-node 版本升级导致的兼容性问题

解决:需要在项目中安装  @types/node 

npm install --save-dev @types/node

效果: 安装  @types/node 后,再运行就能够正常打印日志了

2.2、声明

2.2.1、变量声明

2.2.2、常量声明

 let用于声明变量,而const用于声明常量,两者的区别是变量在赋值后可以修改,而常量在赋值后便不能再修改。

const b:number = 200;

2.2.3、类型推断 

如果一个变量或常量的声明包含了初始值,TS 便可以根据初始值进行类型推断,此时我们就可以不显式指定其类型,例如

let c = 60;
console.log(typeof c); //number

2.3、常用数据类型 

2.3.1、number

number表示数字,包括整数和浮点数,例如: 100-332.5-3.9

let a :number = 100
let b :number = -33
let c :number = 2.5
let d :number = -3.9

2.3.2、string 

string表示字符串,例如: 你好hello

let a:string = '你好'
let b:string = 'hello'

 2.3.3、boolean

boolean表示布尔值,可选值为:truefalse

let isOpen:boolean = true
let isDone:boolean = false

 2.3.4、数组

数组类型定义由两部分组成,元素类型[],例如number[]表示数字数组,string[]表示字符串数组,数组类型的变量可由数组字面量——[item1,item2,item3]进行初始化。

let a: number[] = []
let b: string[] = ['你好', 'hello']

2.3.5、对象 

在TS中,对象(object)是一种一系列由属性名称属性值组成的数据结构,例如姓名:'张三', 年龄:10, 性别:'男'。对象类型的声明需要包含所有属性的名称类型,例如{name: string, age: number, gender: string},对象类型的变量可以通过对象字面量——{name:'张三', age:10, gender:'男'}进行初始化。

let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};

2.4、函数 

2.4.1、函数声明语法

声明函数的基础语法如下

2.4.2、参数

2.4.2.1、特殊语法

①可选参数

可选参数通过参数名后的?进行标识,如以下案例中的gender?参数。

function getPersonInfo(name: string, age: number, gender?: string): string {
    if (gender === undefined) {
        gender = '未知'
    }
    return `name:${name},age:${age},gender:${gender}`;
}

let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);

注:调用函数时,未传递可选参数,则该参数的值为undefined

②默认参数

可在函数的参数列表为参数指定默认值,如以下案例中的gender: string='未知'参数。

function getPersonInfo(name: string, age: number, gender: string='未知'): string {
    return `name:${name},age:${age},gender:${gender}`;
}

let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);
2.4.2.2、 特殊类型

①联合类型

一个函数可能用于处理不同类型的值,这种情况可以使用联合类型,例如以下案例中的message: number | string

function printNumberOrString(message: number | string) {
  console.log(message)
}

printNumberOrString('a')
printNumberOrString(1)

②任意类型

 若函数需要处理任意类型的值,则可以使用any类型,例如以下案例中的message: any

function print(message:any) {
  console.log(message)
}

print('a')
print(1)
print(true)

2.4.3、 返回值

2.4.3.1、特殊类型

若函数没有返回值,则可以使用void作为返回值类型,其含义为空。

function test(): void {
    console.log('hello');
}
2.4.3.2、类型推断

函数的返回值类型可根据函数内容推断出来,因此可以省略不写。

function test() {
    console.log('hello');
}

function sum(a: number, b: number) {
    return a + b;
}

2.4.4、函数声明特殊语法

①匿名函数

匿名函数的语法结构简洁,特别适用于简单且仅需一次性使用的场景。

let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach(function (number) {
    console.log(number);
})

注意:匿名函数能够根据上下文推断出参数类型,因此参数类型可以省略。

②箭头函数

匿名函数的语法还可以进一步的简化,只保留参数列表和函数体两个核心部分,两者用=>符号连接。

let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach((num) => { console.log(num) })

2.5、类

2.5.1、类介绍

类(class)是面向对象编程语言中的一个重要概念。

面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。

类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。例如定义一个 Person类,其对象可以有张三李四等等。

2.5.2、语法说明

2.5.2.1、类的定义

class Person {
    id: number;
    name: string;
    age: number = 18;

    constructor(id: number, name: string) {
        this.id = id;
        this.name = name;
    }

    introduce(): string {
        return `hello,I am ${this.name},and I am ${this.age} years old`
    }
}
2.5.2.2、对象创建

①语法

创建对象的关键字为new,具体语法如下

let person = new Person(1,'zhangsan');

②对象属性的访问

console.log(person.name); //读

person.name = 'lisi'; //写

console.log(person.name);

③对象方法的调用

对象创建后,便可通过对象调用类中声明的方法,如下

let intro = person.introduce();
console.log(intro);
2.5.2.3、静态成员

Typescript 中的类中可以包含静态成员(静态属性和静态方法),静态成员隶属于类本身,而不属于某个对象实例。静态成员通用用于定义一些常量,或者工具方法。

①声明静态成员

定义静态成员需要使用static关键字。

class Constants{
    static count:number=1;
}

class Utils{
    static toLowerCase(str:string){
        return str.toLowerCase();
    }
}

console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));

②使用静态成员

静态成员无需通过对象实例访问,直接通过类本身访问即可。

console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));

2.5.3、继承

继承是面向对象编程中的重要机制,允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。子类可以直接使用父类的特性,并根据需要添加新的特性或覆盖现有的特性。这种机制赋予面向对象程序良好的扩展性。

class Student extends Person {
    classNumber: string;
    constructor(id: number, name: string, classNumber: string) {
        super(id, name);
        this.classNumber = classNumber;
    }

    introduce(): string {
        return super.introduce()+`, and I am a student`;
    }
}

let student = new Student(1,'xiaoming','三年二班');
console.log(student.introduce());

注意:

  • 类的继承需要使用关键字extends
  • 子类构造器中需使用super()调用父类构造器对继承自父类的属性进行初始化。
  • 在子类中可以使用this关键字访问继承自父类的属性和方法。
  • 在子类中可以使用super关键字访问父类定义的方法。

2.5.4、访问修饰符

访问修饰符(Access Modifiers)用于控制类成员(属性、方法等)的可访问性。TypeScript提供了三种访问修饰符,分别是privateprotectedpublic

class Person {
    private id: number;
    protected name: string;
    public age: number;

    constructor(id: number, name: string, age: number) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

class Student extends Person {
    
}

说明:

  • private 修饰的属性或方法是私有的,只能在声明它的类中的被访问。
  • protected 修饰的属性或方法是受保护的,只能在声明它的类和其子类中被访问。
  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的。

2.6、接口

2.6.1、接口介绍

接口(interface)是面向对象编程中的另一个重要概念。接口通常会作为一种契约或规范让类(class)去遵守,确保类实现某些特定的行为或功能。

2.6.2、语法说明

①接口定义

接口使用interface关键字定义,通常情况下,接口中只会包含属性和方法的声明,而不包含具体的实现细节,具体的细节由其实现类完成。

interface Person {
    id: number;
    name: string;
    age: number;
  
    introduce(): void;
}

②接口实现

接口的实现需要用到implements关键字,实现类中,需要包含接口属性的赋值逻辑,以及接口方法的实现逻辑。

class Student implements Person {
    id: number;
    name: string;
    age: number;

    constructor(id: number, name: string, age: number) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    introduce(): void {
        console.log('Hello,I am a student');
    }
}

2.6.3、多态

多态是面相对象编程中的一个重要概念,它可以使同一类型的对象具有不同的行为。下面我们通过一个具体的案例来体会多态这一概念

首先,再创建一个Person接口的实现类Teacher,如下

class Teacher implements Person {
    id: number;
    name: string;
    age: number;

    constructor(id: number, name: string, age: number) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    introduce(): void {
        console.log('Hello,I am a teacher');
    }
}

然后分别创建一个Student对象和一个Teacher对象,注意两个对象的类型均可以设置Person,如下

let p1: Person = new Student(1, 'zhangsan', 17);
let p2: Person = new Teacher(2, 'lisi', 35);

最后分别调用p1p2introduce()方法,你会发现,同样是Person类型的两个对象,调用同一个introduce()方法时,表现出了不同的行为,这就是多态

p1.introduce();//Hello,I am a student
p2.introduce();//Hello,I am a teacher

2.6.4、接口的作用

在传统的面向对象编程的场景中,接口主要用于设计和组织代码,使代码更加容易扩展和维护。

假如现在需要实现一个订单支付系统,按照面向对象编程的习惯,首先需要定义一个订单类(Order),如下

class Order {
    totalAmount: number;

    constructor(totalAmount: number) {
        this.totalAmount = totalAmount;
    }

    pay() {
        console.log(`AliPay:${this.totalAmount}`);
    }
}

很容易预想到,这个系统将来可能需要支持其他的支付方式,为了方便代码支持新的支付方式,我们可以对代码进行如下改造。

首先定义一个支付策略的接口,接口中声明一个pay方法,用来规范实现类必须实现支付逻辑。

interface PaymentStrategy {
    pay(amount: number): void;
}

然后在订单类中增加一个PaymentStrategy的属性,并且在订单类中的pay方法中调用PaymentStrategypay方法,如下

class Order {
    totalAmount: number;
    paymentStrategy: PaymentStrategy;

    constructor(totalAmount: number, paymentStrategy: PaymentStrategy) {
        this.totalAmount = totalAmount;
        this.paymentStrategy = paymentStrategy;
    }

    pay() {
        this.paymentStrategy.pay(this.totalAmount);
    }
}

这样改造完之后,就可以很容易的在不改变现有代码的情况下,支持新的支付方式了。

比如现在需要支持AliPay,那我们就可以创建AliPay这个类(class)并实现(implement)PaymentStrategy这个接口,如下

class AliPay implements PaymentStrategy {
    pay(amount: number): void {
        console.log(`AliPay:${amount}`);
    }
}

这样一来,之后创建的订单就可以使用AliPay这个支付方式了。

let order = new Order(1000,new AliPay());
order.pay();

2.6.5、TS中接口的特殊性

TypeScript 中的接口是一个非常灵活的概念,除了用作类的规范之外,也常用于直接描述对象的类型,例如,现有一个变量的定义如下

let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};

可以看到变量的值为一个一般对象,变量的类型为{name:string, age:number, gender:string},此时就可以声明一个接口来描述该对象的类型,如下

interface Person {
    name: string;
    age: number;
    gender: string;
}

let person: Person = {name:'张三', age:10, gender:'男'};

2.7、枚举

2.7.1、枚举介绍

枚举(Enumeration)是编程语言中常见的一种数据类型,其主要功能是定义一组有限的选项,例如,方向(上、下、左、右)或季节(春、夏、秋、冬)等概念都可以使用枚举类型定义。

2.7.2、语法说明

①枚举定义

枚举的定义需使用enum关键字,如下

enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
}

②枚举使用

枚举的使用记住两个原则即可

  • 枚举值的访问

像访问对象属性一样访问枚举值,例如Season.SPRING

  • 枚举值的类型

枚举值的类型为enum的名称,例如Season.SPRINGSeason.SUMMER等值的类型都是Season

let spring:Season = Season.SPRING;

③使用场景

现需要编写一个函数move,其功能是根据输入的方向(上、下、左、右)进行移动,此时就可以先使用枚举定义好所有可能的输入选项,如下

enum Direction {
    UP,
    BOTTOM,
    LEFT,
    RIGHT
}

move函数的实现如下

function move(direction: Direction) {
    if(direction===Direction.UP){
        console.log('向上移动');
    }else if(direction===Direction.BOTTOM){
        console.log('向下移动');
    }else if(direction===Direction.LEFT){
        console.log('向左移动');
    }else{
        console.log('向右移动');
    }
}

move(Direction.UP);

2.7.3、赋值

在TypeScript 中,枚举实际上是一个对象,而每个枚举值都是该对象的一个属性,并且每个属性都有具体的值,属性值只支持两种类型——数字或字符串。

默认情况下,每个属性的值都是数字,并且从 0 开始递增,例如上述案例中的Direction枚举中,Direction.UP的值为0Direction.BOTTOM的值为1,依次类推,具体如下

console.log(Direction.UP) //0
console.log(Direction.BOTTOM) //1
console.log(Direction.LEFT) //2
console.log(Direction.RIGHT) //3

除了使用默认的数字作为属性的值,我们还能手动为每个属性赋值,例如

enum Direction {
    UP = 1,
    BOTTOM = 2,
    LEFT = 3,
    RIGHT = 4
}

console.log(Direction.UP) //1
console.log(Direction.BOTTOM) //2
console.log(Direction.LEFT) //3
console.log(Direction.RIGHT) //4

再例如

enum Direction {
    UP = 'up',
    BOTTOM = 'bottom',
    LEFT = 'left',
    RIGHT = 'right'
}

console.log(Direction.UP) //up
console.log(Direction.BOTTOM) //bottom
console.log(Direction.LEFT) //left
console.log(Direction.RIGHT) //right

通过为枚举属性赋值,可以赋予枚举属性一些更有意义的信息,例如以下枚举

enum Color {
    Red = 0xFF0000,
    Green = 0x00FF00,
    Blue = 0x0000FF
}

enum FontSize {
    Small = 12,
    Medium = 16,
    Large = 20,
    ExtraLarge = 24
}

2.8、模块化

2.8.1、模块化介绍

模块化是指将复杂的程序拆解为多个独立的文件单元,每个文件被称为一个模块。在 TypeScript 中,默认情况下,每个模块都拥有自己的作用域,这意味着在一个模块中声明的任何内容(如变量、函数、类等)在该模块外部是不可见的。为了在一个模块中使用其他模块的内容,必须对这些内容进行导入导出

2.8.2、语法说明

①导出

导出须使用export关键字,语法如下

export function hello() {
    console.log('hello module A');
}

export const str = 'hello world';

const num = 1;

②导入

导入须使用import关键字,语法如下

import { hello, str } from './moduleA';

hello();
console.log(str);

2.8.3、避免命名冲突

若多个模块中具有命名相同的变量、函数等内容,将这些内容导入到同一模块下就会出现命名冲突。例如,在上述案例的基础上,又增加了一个 moduleC,内容如下

export function hello() {
    console.log('hello module C');
}

export const str = 'module C';

moduleB 同时引入 moduleA 和 moduleC 的内容,如下,显然就会出命名冲突

import { hello, str } from "./moduleA";
import { hello, str } from "./moduleC";

hello() //?
console.log(str); //?

①导入重命名

import { hello as helloFromA, str as strFromA } from "./moduleA";
import { hello as helloFromC, str as strFromC } from "./moduleC";

helloFromA();
console.log(strFromA);

helloFromC();
console.log(strFromC);

②创建模块对象

上述导入重命名的方式能够很好的解决命名冲突的问题,但是当冲突内容较多时,这种写法会比较冗长。除了导入重命名外,还可以将某个模块的内容统一导入到一个模块对象上,这样就能简洁有效的解决命名冲突的问题了,具体语法如下

import * as A from "./moduleA";
import * as C from "./moduleC";

A.hello();
console.log(A.str);

C.hello();
console.log(C.str);

2.8.4、默认导入导出

①默认导出

默认导出允许一个模块指定一个(最多一个)默认的导出项,语法如下

export default function hello(){
    console.log('moduleA');
}

②默认导入

由于每个模块最多有一个默认导出,因此默认导入无需关注导入项的原始名称,并且无需使用{}

import helloFromA from "./moduleA";

由于默认导入时无需关注导入项的名称,所以默认导出支持匿名内容,比如匿名函数,语法如下 

export default function () {
    console.log('moduleB');
}

最后:👏👏😊😊😊👍👍 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/401700.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣 面试题 05.06. 整数转换

思路: 牵扯到二进制数,基本上要考虑位运算符,相关知识可以见http://t.csdnimg.cn/fzts7 之前做过类似的题目,大致思路就是先用按位异或^找出不同位,再用n&(n-1)计算出不同位的个数&#x…

nuxt项目搭建

1.先下载nuxt脚手架 yarn create nuxt-app <项目名>&#xff0c;记得安装完项目&#xff0c;npm i,下载node包 目录介绍 components 存放组件分别是头部&#xff08;包含导航&#xff09;和底部 layouts 页面布局&#xff0c;实现一个页面整体架构规则&#xff0c;头…

Sora 全网最全资料

大家好,本资料库是全网集体智慧的结晶,通过这个资料库,我们希望能够为读者提供一个全方位、多角度了解和研究Sora大模型的平台。每一部分都旨在深入探讨Sora大模型的不同方面,从技术细节到社会影响,再到未来展望,以确保读者能够获得最全面的信息和洞见。 📁一. 概念和…

yolov5导出onnx转engine推理

yolov5导出注意事项 配置 需要提供配置文件和权重文件&#xff0c;不然导出模型不能正常推理。 默认提供检测头。 ModuleNotFoundError: No module named ‘tensorrt’安装TensorRT-python发现报错 由于ModuleNotFoundError: No module named ‘tensorrt’安装TensorRT-pyt…

Android14 InputManager-InputManagerService环境的构造

IMS分为Java层与Native层两个部分&#xff0c;其启动过程是从Java部分的初始化开始&#xff0c;进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start&#xff08;&#xff09;函数完成启动 同其他系统服务一样&#xff0c;IMS在SystemServer中的ServerT…

不要抱怨,不如抱 Java 运算符吧 (1)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

mplfinance 使用make_addplot做复杂股票走势图

mplfinance 使用make_addplot做复杂股票走势图 1.代码 import talib as tb import pandas as pd import mplfinance as mpfimport matplotlib.pyplot as pltplt.rcParams[font.sans-serif][simHei] # 以黑体显示中文 plt.rcParams[axes.unicode_minus]False # 解决保存图像符…

Meta 发布 MMCSG (多模态智能眼镜对话数据集)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

LeetCode 热题 100 Day01

哈希模块 哈希结构&#xff1a; 哈希结构&#xff0c;即hash table&#xff0c;哈希表|散列表结构。 图摘自《代码随想录》 哈希表本质上表示的元素和索引的一种映射关系。 若查找某个数组中第n个元素&#xff0c;有两种方法&#xff1a; 1.从头遍历&#xff0c;复杂度&#xf…

Java 学习和实践笔记(15):面向过程和面象对象其实很简单!

学完这一节&#xff0c;才真正明白了什么叫面向对象和面向过程&#xff0c;其实很简单~ 第一个例子&#xff1a;怎样把大象装进冰箱 这个很清楚很容易地可以列出第一步。 第二个例子&#xff1a;怎样制造一台汽车 这个就很难确定哪一步做第一步。 面向过程和面向对象的区别 …

【二十六】【C++】Map和Set

K模型与KV模型 在数据结构中&#xff0c;二叉搜索树&#xff08;BST&#xff09;的应用通常围绕着两种基本模型&#xff1a;键模型&#xff08;K模型&#xff09;和键值对模型&#xff08;KV模型&#xff09;。这两种模型定义了树中节点存储数据的方式&#xff0c;以及如何通过…

区块链游戏解说:什么是 Planet IX

作者&#xff1a;lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a;Planet IX Dashboard 什么是 Planet IX Planet IX&#xff0c;一个由原生 IX TOKEN 推动的 Web3 玩赚平台。作为一款 GameFi 策略游戏&#xff0c; Planet IX 上的每项资…

如何修改docker容器的端口映射

要修改 Docker 容器的端口映射&#xff0c;你需要停止并删除现有的容器&#xff0c;然后使用新的端口映射重新运行容器。以下是详细步骤&#xff1a; 停止容器&#xff1a; 使用 docker stop 命令停止正在运行的容器。替换 <container_id> 为你要停止的容器的 ID 或者容器…

浅谈消防设备电源监控系统在高层建筑中的应用

摘要&#xff1a;火灾发生后&#xff0c;非消防电源被切断&#xff0c;火灾报警系统应立即接通消防电源&#xff0c;满足消防设施 处于良好运行状态&#xff0c;对消防设备电源状态的监控是十分必要的。介绍消防设备电源的重要性 和三种类型&#xff0c;分析消防设备电源监控系…

Python中HTTP重定向和重定向链的处理:网络迷宫的导航专家

在网络世界里&#xff0c;有时候&#xff0c;我们访问的URL并不是直接指向我们想要的内容&#xff0c;而是像是一个神秘的迷宫&#xff0c;指引我们绕来绕去。这时候&#xff0c;HTTP重定向就像是迷宫里的路标&#xff0c;告诉我们“嘿&#xff0c;你要找的东西不在这里&#x…

这才是No.1的门禁管理技巧!赶紧抄作业

随着社会的不断发展和科技的飞速进步&#xff0c;安全管理成为各个领域不可或缺的重要环节。在这个背景下&#xff0c;门禁监控系统作为一种先进而高效的安全管理工具逐渐受到了广泛关注和应用。 客户案例 企业大厦管理 在江苏某繁忙的商业大厦中&#xff0c;管理人员常常面临…

【咕咕送书 | 第七期】世界顶级名校计算机专业,都在用哪些书当教材?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 写在前面参与规则 ✅参与方式&#xff1a;关注博主、点赞、收藏、评论&#xff0c;任意评论&#xff08;每人最多评论…

七、计算机视觉-图像的ROI区域

文章目录 1、什么是ROI2、ROI如何实现的3、一个案例总结 1、什么是ROI 在计算机视觉中&#xff0c;ROI代表感兴趣区域&#xff08;Region of Interest&#xff09;&#xff0c;它是指图像或视频中被指定为需要特别关注或处理的区域。ROI可以帮助减少计算量&#xff0c;并且在处…

基于JAVA springboot+mybatis 电商书城平台系统设计和实现

基于JAVA springbootmybatis 电商书城平台系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获…

初识VUE3

1.VUE3官网 https://cn.vuejs.org/ 2.通过Vite创建项目 全局安装vite npm config set registryhttps://registry.npmmirror.com 使用国内源npm install -g vitelatest 安装vite前要先查看镜像源地址并使用国内镜像源地址 //查看镜像源地址 npm config get registry //更…