十年未睡,呕心沥血写出来的TypeScript心得
内容偏长,建议先马后看
- 概述
- 重点问题
- 内容概要
- 强类型与弱类型
- 静态类型与动态类型
- JS类型系统特征
- 弱类型的问题
- 强类型的优势
- TS语言规范与基本使用
- TS概述
- TS快速使用
- TS配置文件
- 原始数据类型
- 标准库声明
- 中文错误消息
- 作用域问题
- Object类型
- 数组类型
- 元组类型
- 枚举类型
- 函数类型
- 任意类型
- 隐式类型推断
- 类型断言
- 接口
- 接口补充
- 类的基本使用
- 类的访问修饰符
- 类的只读属性
- 类与接口
- 抽象类
- 泛型
- 类型声明
概述
- TS是一门基于JS之上的编程语言
- 解决了JS类型系统的问题
- TS大大提高代码的可靠程度
重点问题
- JS自有类型系统的问题
- 如何借助一些优秀的技术方案解决该问题
- TS只是在这个个过程当中我们会涉及到的一门语言
- 因为TS这门语言目前可以说是此类问题的最终极解决方案,所以我们会着重讲解
- 除此之外,也会介绍一些其他的相关技术方案
内容概要
- 强类型与弱类型
- 静态类型与动态类型
- JS自有类型系统的问题
- TS语言规范与基本使用
强类型与弱类型
- 区分不同编程语言时经常提起的名词
- 强类型与弱类型(类型安全)
- 静态类型与动态类型(类型检查)
- 类型安全
- 强类型 vs 弱类型
- 强类型:在语言层面限制函数的实参类型必须要跟形参类型完全相同
class Main {static void foo (int num) {System.outprintln(num);}public static void main(String[]) {Main.foo(100); // 100Main.foo("100"); // error "100" is a stringMain.foo(Integer.parseInt("100")); // ok} }
- 弱类型:在语言层面不会限制实参的类型
function foo (num) {console.log(num) } foo(100) // ok foo('100') // ok foo(pareseInt('100')) // ok
- 由于这种强弱类型之分根本不是某一个权威机构的定义,而且也没有给出一个具体的规则,所以对于这种界定方式的细节出现了不一样的理解
- 但整体上大家的界定方式都是在描述:
- 强类型有更强的类型约束
- 弱类型中几乎没有什么约束
- 个人比较认同的一个说法是:
- 强类型语言中不允许任意的隐式类型转换
- 弱类型语言当中允许任意的隐式类型转换
console.log('100' - 50) // 50console.log(Math.floor('foo')) // NaNconsole.log(Math.floor(true)) // 1
- 变量类型允许随时改变的特点,不是强弱类型的差异
- 比如python就是强类型的语言,但是他的变量类型随时可以改变
- 这点在很多资料当中可能都表示的有些不太妥当,因为大都在说pythpn是一门弱类型语言,其实并不是
- 强类型 vs 弱类型
静态类型与动态类型
- 类型检查
- 静态类型与动态类型
- 静态类型:一个变量声明时它的类型就是明确,声明过后类型不允许修改
- 动态类型:运行阶段才能够明确一个类型,而且变量的类型随时可以改变
- 动态语言中,变量是没有类型的,变量中存放的值是有类型的
var foo = 100 // number类型 foo = 'bar' // 字符串 console.log(foo)
- 静态类型与动态类型
JS类型系统特征
- JS是一门弱类型且动态类型的语言
- 语言本身的类型系统是很薄弱的,甚至我们也可以说JS就没有类型系统
- 这种语言的特征可以被称之为:任性!
- 因为他几乎没有任何的类型限制,所以说JS这门语言是特别的灵活多变
- 但在这种表象背后,丢失掉的就是类型系统的可靠性,我们在代码当中每遇到一个变量我们都需要去担心他到底是不是我想要的类型
- 整体感受可以被称之为:不靠谱!
- 为什么JS不是强类型或者静态类型的帮助
- 与JS的背景有关,早前JS的应用就没想到会发展到今天这种规模,比较简单可能几十行代码或者一百多行代码就能完成功能
- 在这种一眼看到头的情况下,类型系统的限制就比较多余了,或者说很麻烦
- JS是一门脚本语言,脚本语言的特点就是:不需要编译就直接在运行环境中去运行
- 换句话说:JS没有编译环节,所以就算是设计为了静态类型语言也没什么意义,因为静态类型需要在编译阶段进行编译检查,而JS根本没有这样一个环节
- 所以JS是一门更灵活更多变的弱类型动态语言
- 在当时没有问题,在当时甚至也是优势,但是现在前端应用的规模已经完全不同了,遍地都是大规模应用,所以JS代码就越来越复杂,开发周期也越来越长,这种情况下,之前的优势也就成为了短板
- 与JS的背景有关,早前JS的应用就没想到会发展到今天这种规模,比较简单可能几十行代码或者一百多行代码就能完成功能
弱类型的问题
- 问题异常要等到运行时才能发现
const obj = {} /*** obj中没有这个方法,但是在语法层面是可以这样写的,只是在运行时会报错* 也就是说,在JS这种弱类型的语言当中,我们就必须要等到运行阶段我们此案呢过发现代码当中的类型异常* */
obj.foo() // TypeError: obj.foo is not a function
/*** 而且我们这里如果不是立即执行该方法,而是在某一个特定的时间才去执行* * 那程序在刚运行时没办法发现异常,直到在代码执行后才会去抛出错误* * 这也就是说,如果我们在测试的过程中,没有测试到这行代码,这样一个隐患就会被留到代码当中* * 而如果是强类型的语言这里我们直接去调用对象当中一个不存在的成员,这语法上直接就会报错,不用等到运行的回收才会报错* */
setTimeout(() => {obj.foo() //TypeError: obj.foo is not a function
}, 1000)
- 类型不明确,会造成函数功能有可能发生改变
function sum (a, b) {return a + b
}console.log(sum(100, 200)) // 300
console.log(sum(100, '200')) // 100200
/*** 这就是因为类型不确定所造成的一个典型的问题* * 我们虽可以通过约定的方式去规避这样的问题,但是约定是没有任何保障的,特别是在多人协同开发时* * 我们不能保证每个人遵循所有的约定* * 而我们是用强类型语言的话,这种情况会被彻底避免掉,因为在强类型语言当中,我们要求传入数字,那传入字符串就会直接报错* */
- 对对象索引器的一种错误用法
const obj = {}obj[true] = 100console.log(obj['true'])/*** 我们想创建一个对象,通过索引器的方式去给他赋值* * 对象的属性名只能是字符串或者是ES6推出的Symbol* * 但是由于JS是弱类型的,所以这里可以在索引器当中使用任意类型的值作为对象的属性名,在其内部会自动转换为字符串* * 我们这里使用布尔值作为属性名,最终会转换为字符串true的形式* * 如果我们不知道对象属性名会自动转换为字符串的特点,这里可能会感觉很奇怪* * 这种奇怪的根源可能就是我们用的是比较随意的弱类型语言,如果是强类型语言这种问题可能就会被避免* * 因为在强类型语言中他明确有类型要求,不满足的在语法上就行不通* */
- 这只是弱类型问题的冰山一角
- 弱类型语言的弊端是非常明显的,只是在代码量小的情况下可以通过约定的方式规避,而对于一些开发周期比较长的大型项目,这种君子约定还是有一定的隐患,只有在语法层面的强制要求才能够提供更可靠地保障
- 强类型语言的代码在代码可靠程度上有明显优势,使用强类型语言就可以提前消灭一大批有可能存在的类型异常,而不必等到在运行过程中慢慢的debug
强类型的优势
- 错误更早暴露
- 在编码阶段提前消灭一大部分类型异常
- 代码更智能,编码更准确
- 开发者最需要的一点
function render (element) {// element./*** 这时智能提示不能提示出来很有用的内容* * 这就是因为开发工具这里根本没有办法去推断出来这个element到底是什么类型的* * 所以没办法知道这里边有哪些具体的成员* * 这时候只能凭借记忆去访问对象当中的成员* * 所以也导致了可能会出现单词拼写错误或者名称记错之类的造成一些问题* * 如果是强类型语言,那编译器,时时刻刻都知道是哪一个类型,所以能够提供出来更准确的智能提示* */ }
- 重构更牢靠
- 对代码有一些破坏性的改动时,例如删除对象当中的某个后才成员,或者是修改一个已经存在的成员名称
const util = {aaa: () => {console.log('util func')} } /** * 这个对象的aaa方法如果在很多地方有使用的话,我们是不能随意修改的 * * 因为JS弱类型的语言,修改了这个属性的名称过后,很多地方用到的名称还是以前的,即便有错误,也不会立即表现出来 * * 强类型的语言,一但属性名发生了变化就会立即报出错误,这时候可以轻松定位所有使用到的地方,然后修改 * * 甚至是有些工具,可以吧所有引用到这个对象当中的成员的地方,自动修改 * */
- 减少不必要的类型判断
- 强类型的语言在代码层面会减少一些我们类型判断
function sum (a, b) {if (typeof a === 'number' || typeof b === 'number') {throw new TypeError('arguments must be a number')}return a + b }
TS语言规范与基本使用
TS概述
- 一门基于JS基础之上的超集(扩展及)语言
- 超集:在JS原有基础之上多了一些扩展特性
- 多出来的就是一套更强大的类型系统以及对ES新特性的支持
- 最终会被编译为原始JS
- TS中类型系统的优势
- 在Flow中已经所有体会,两者是很相似的,无外乎就是帮我们避免在开发过程当中有可能会出现的类型异常,去提高我们代码的效率与可靠程度
- 新特性的支持
- ES在近几年迭代了很多非常有用的新功能,但很多时候在陈旧环境中会有兼容性的问题,TS支持自动转换这些新特性,所以在TS中可以立即使用新特性
- 即便说我们不需要这种强类型系统,通过TS去使用ES的新特性也是一个很好的选择
- 我们之前是通过babel去转换JS当中一些新特性,其实TS在这方面和babel是类似的,因为TS最终可以选择最低为ES3版本的编码,所以兼容性特别好
- 因为TS最终编译为JS去工作,所以任何一个JS运行环境下都可以使用TS进行开发,例如传统的浏览器应用,node应用,React.native应用
- 相比较之前的Flow来说,TS作为一名完整的编程语言,功能更为强大,生态也更健全,更完善,特别说对开发工具这一块!
- 目前很多大型项目开始使用TS开发
- Angular
- Vue.js 3.0
- TS — 前端领域中的第二语言
- 小项目 — 需要灵活自由,可以选择JS本身
- 大项目 — 所有人建议使用TS
- 缺点
- 语言本身多了很多概念
- 接口,泛型,枚举…
- 多了这些概念后会增加我们的学习成本与时间周期,好在TS属于渐进式
- 渐进式:即便我们什么特性都不知道,我们也可以立马去按照JS标准语法去编写TS代码,换句话说,我们完全可以把它当作JS去使用,然后在学习过程当中了解一个特性,就可以去使用一个特性
- 周期比较短的项目,TS会增加一些成本
- 因为在项目初期编写很多的类型声明,比如对象,比如函数,都会有很多类型声明需要我们去编写
- 如果是长期维护的大型项目这点成本就不算什么,而且很多时候算是一劳永逸的,所以TS给我们带来的优点是远大于缺点的
- 语言本身多了很多概念
- 整体来说,TS会随着我们前端的发展成为一门必要的语言
TS快速使用
- 安装
- 指令:
- yarn init -yes || npm init -y
- yarn add typescript --dev || npm i typescript -d
- yarn tsc 文件名 || tsc 文件名
- 因为TS本身就是一个npm的模块,可以选择安装到全局,但考虑到项目依赖的问题,我们安装到项目当中更加合理
- 指令:
- 安装结束这个模块就会在我们node_modules中的.bin这个目录下多出一个tsc的一个命令
- 作用:
- 帮我们编译TS代码
- 先去检查代码中的类型使用异常
- 移除类型注解之类的扩展语法
- 自动转换ES新特性
- 一套更强大的类型系统
- 帮我们编译TS代码
- 作用:
TS配置文件
- tsc这个命令不仅仅可以编译指定某个TS文件,还可以用来去编译整个项目,或者编译整个工程
- 编译之前先要创建一个配置文件
- yarn tsc --init || tsc --init
- 在这个文件中,默认只有一个compilerOptions的属性
- 这个属性是TS编译器所对应的一些配置选项
- 其中绝大多数都注释掉,在每个选项上也都会有一些简要的说明
- 最常用的选项
- target — 设置编译后的JS所采用的ES标准
- module — 输出的代码会采用什么样的方式模块化
- outdir — 编译结果输出到的文件夹
- rootDir — 源代码(TS)所在的文件夹
- sourceMap — 开启源代码映射,能让我们在调试的时候使用sourceMap去调试TS源代码
- strict — 开启所有严格检查选项,对于类型的检查会变得十分严格
- 注意:
- 我们有了tsconfig.json这个配置文件过后,我们再去使用tsc命令时就可以去使用这个配置文件了
- 但是如果还是使用tsc去编译某一个指定的文件,这个配置文件就不会生效,只有直接运行tsc这个命令编译整个项目时,配置文件才会自动生效
- 直接 tsc 不仅会生成一个js文件,还有对应的sourceMap文件
原始数据类型
- JS六种原始数据类型在TS中的基本应用
// 原始数据类型
const a: string = 'foobar'const b: number = 100 // NaN Infinityconst c: boolean = true // false/*** 这三种类型相比较Flow中有所不同,TS中是允许为空的* * 但是这里显示为错误的,这是因为严格模式和默认模式之间的差异* * 需要关闭strict,然后这里就不报错了* * 在非严格模式,string number boolean可以为空,严格模式是不允许的* * strict是开启了所有的严格模式的选项,如果只是要去检查我们的变量不能为空* * 我们可以使用strictNullChecks --- 检查变量不能为空* */ // const d: string = null/*** void --- 空值,一般在函数没有返回值的时候用来标记函数返回值的类型* * 只能存放null/undefined 严格模式下,只能为undefined* */
const e: void = undefinedconst f: null = nullconst g: undefined = undefined/*** 只能存放Symbol()类型的值* * 直接使用时会报错,欲知详情如何,且听下回分解~* */
// const h: symbol = Symbol()
标准库声明
- 内置对象类型
- 上边我们尝试使用全局的Symbol函数,创建一个symbol会报错
- 为什么?
- Symbol实际上时JS的一个内置的标准对象,就像Array,Object性质是相同的,只不过Symbol是ES6新增的,对于这种内置的对象,其实它自身也是有类型的,而且这些内置的类型都在TS当中已经帮我们定义好了
- 解决:
- 将target修改为es2015即可
- lib选项去指定我们引用的标准库
- 这时打开01文件内部的console会报错
- console对象在浏览器中是BOM对象提供的,而我们刚刚所设置的lib当中只设置了ES2015,所以所有的标准库都被覆盖掉了,这里需要将所有默认的标准库再添加回来
- TS中将BOM/DOM都归为一个DOM标准库当中
- 这时打开01文件内部的console会报错
- 标准库
- 内置对象所对应的声明文件
- 在代码中使用内置对象,就必须要引用对应的标准库,否则TS找不到对应的类型,就会报错
中文错误消息
- TS是支持多语言化的错误消息,默认会根据操作系统和开发工具的语言设置选择一个错误消息的语言
- 在使用tsc命令时加上一个 --locale zh-CN
yarn tsc --locale zh-CN || tsc --locale zh-CN
作用域问题
- 我们在学习TS的过程当中,肯定会涉及到在不同的文件当中去尝试TS的一些不同的特性,这种情况下可能会遇到不同文件当中有相同变量名称的情况
// const a = 123
/*** const a: 123* 无法重新声明块范围变量“a”。ts(2451)* 02-原始数据类型.ts(2, 7): 此处也声明了 "a"。* */
- 解决
- 自调用函数
(function () {const a = 123 })()
- 使用export导出,也就是使用ESmodules,这样可以将文件作为一个文件模块,模块是有单独的模块作用域的
const a =123export {}
- 这种问题在实际开发时一般不会用到,因为在绝大多数中,我们每个文件都会以一个模块来工作,只不过我们后边每一个案例,里边难免会用到一些重复的变量
Object类型
- TS中的Object并不单指对象类型,而是泛指所有的非原始类型
- 对象,数组,函数
- 在TS中限制对象类型,我们应该使用更为专业的接口,接口我们会有专门的介绍
- 这里我们只需要知道两点
- object类型他并不单指对象,而是除了原始类型之外的其他类型
- 对象的类型限制,我们可以使用这种类似对象字面量的语法方式,但是更专业的方式时使用接口
export {} //仅是为了作用域,实际开发不需要const foo: object = function () {} // {} [] function(){}/*** 如果我们需要一个普通的对象类型,我们要使用类似对象字面量的语法去标记* * 限制对象obj必须要有一个foo的属性,属性值必须为number,多个成员时逗号间隔继续添加* * 对象类型限制的要求:赋值的对象结构,必须要和我们这里类型的结构完全一致,不能多也不能少** 也就是说如果多出来一个属性,语法上就会报出类型错误* * */
const obj: { foo: number, bar: string } = {foo: 123, bar:'TS'}
数组类型
- TS当中定义数组的方式和Flow的方式完全一致,他也有两种方式
- 使用Array泛型
- 使用元素类型 + []
// 纯数字组成的数组 const arr1: Array<number> = [1, 2, 3] const arr2: number[] = [1, 2, 3]
- 在TS中使用强类型的优势
// function sum ( ...args ) {
// return args.reduce((prev, current) => prev + current, 0)
// }
/*** 如果是JS,我们就需要担心sum接收到的参数类型* * 很多时候我们需要加上一大堆判断,确保每一个参数都是number* * 但在TS中就只需要给这个类型去添加一个 数字数组的类型注解* */
function sum ( ...args: number[] ) {return args.reduce((prev, current) => prev + current, 0)
}// sum(1, 2, '3') // 传入错误值就会报错
元组类型
- 特殊的数据结构
- 元组 — 明确元素数量以及每一个元素类型的一个数组
- 各个元素的元素类型没必要完全相同,在TS当中可以使用类似数组字面量的语法去定义元组类型
- 一般会用来在一个函数中返回多个返回值
- React当中的useState这个hook当中,我们返回的就是一个元组类型
- ES2017当中的Object.entries()这个方法获取一个对象当中所有的键值数组,得到的每一个键值就是一个元组,因为他是一个固定长度的
export {}const tuple: [number, string] = [1, 'hhh']
// 只能存放一个number和字符串,不能多也不能少// 可以使用数组下标的方式访问元组的元素
// const age = tuple[0]
// const name = tuple[1]// 数组结构也可以提取到每一个元素
const [age, name] = tupleObject.entries({foo: 123,bar: 456
})
枚举类型
- 我们在应用开发过程中,经常会用到某几个数值,去代表某种状态
- 特点
- 可以给一组数值分别取上一个更好理解的名字
- 一个枚举值,只会存在几个固定的值,不会出现超出范围的可能性
- 很多传统的编程语言当中,枚举是一个很常见的数据结构,但在JS中并没有这种数据结构
- 很多时候我们都需要使用一个对象模拟实现枚举
const PostStatus = {Draft: 0,Unpublished: 1,Published: 2
}const post = {title : 'hello TS',content: 'TS is a typed superset of JavaScript',status: PostStatus.Draft // 2 // 1 // 0
}
- 在TS中用一个专门的枚举类型我们可以使用enum这个关键词去声明一个枚举
enum PostStatus {Draft = 0,Unpublished = 1,Published = 2
}const post = {title : 'hello TS',content: 'TS is a typed superset of JavaScript',status: PostStatus.Draft // 2 // 1 // 0
}
- 注意点
- 这里使用的是 赋值号 而不是 冒号
- 枚举类型的只可以不用去使用赋值号指定,不指定的话会默认从0开始累加,
- 如果给枚举当中第一个成员指定了具体的值,会变得值会在这个基础之上累加
- 枚举的值可以是number之外,也可以是string,也就是字符串枚举
- 由于字符串无法像数字一样自增,所以如果是字符串枚举的话,需要我们手动给每一个成员初始化一个明确的初始化的值
- 字符串枚举并不常见
// enum PostStatus { // Draft, // Unpublished, // Published // }// enum PostStatus { // Draft = 6, // Unpublished, // Published // }enum PostStatus {Draft = 'a',Unpublished = 'b',Published = 'c' }enum PostStatus {Draft,Unpublished,Published }const post = {title : 'hello TS',content: 'TS is a typed superset of JavaScript',status: PostStatus.Draft // 2 // 1 // 0 }
- 关于枚举我们还需要了解一点
- 枚举类型会入侵到我们运行时的代码
- 换句话说就是:他会影响我们编译后的结果
- 我们在TS中使用的大多数类型他在经过编译转换过后最终都会被移除掉,但是枚举不会,最终会编译为双向的键值对对象
- 双向键值对 — 通过键可以获取值,也可以通过值再去获取键
- 目的是
- 可以动态的根据枚举值,去获取枚举的名称,也就是说在代码当中可以通过索引器的方式去获取对应的名称
- 如果确定在代码中不会使用索引器的方式去访问枚举,那我们建议大家使用常量枚举
- 常量枚举的用法就是在enum这个关键词前加上一个const
函数类型
- 对函数的输入输出进行限制,也就是参数与返回值
- 在JS中有两种函数定义的方式
- 函数声明
- 函数表达式
- 这里需要了解两种方式下函数如何进行类型的约束
export {}// function fnuc (a: number, b: number): string {
// return 'func'
// }
// 参数限制为number,返回值限制为string;形参与实参必须完全一致,从类型到数量
// fnuc(1, 2)// 可选参数
// function fnuc (a: number, b?: number): string {
// return 'func'
// }
// fnuc(1)// 或者使用参数默认值,也可以让其成为可选参数
// function fnuc (a: number, b: number = 100): string {
// return 'func'
// }
// fnuc(1)// 不管可选参数还是默认参数,都要出现在参数列表的最后
// 参数会按照位置进行传递,如果可选参数出在了必选参数的前边,那必选参数就没法拿到正确的参数// 任意参数
function fnuc (a: number, b: number = 100, ...rest: number[]): string {return 'func'
}
fnuc(1)// 函数表达式
const func1 = function (a: number, b: number): string {return 'func1'
}
/*** 这个函数表达式最终会放到一个变量当中的,接受这个函数的变量也应该是有类型的* * 一般TS可以根据我们这个函数表达式推断出来我们变量的类型* * 如果我们是把一个函数作为参数传递,也就是作为回调函数这种方式* * 作为回调函数这种情况下,我们就必须要去约束这个回调函数这个参数的类型* * 这种情况就可以使用类似箭头函数的方式去表示我们的参数可以接受什么样一个函数* * 这种方式在定义接口时会经常用到* */
任意类型
- 由于JS自身时弱类型的关系,很多内置的API本身就支持接收任意类型的参数
- 而TS又是基于JS之上的,所以我们难免会在代码中需要用一个变量去接收任意类型的数据
- 注意:
- any类型仍然属于动态类型,特点和普通的JS变量是一样的,可以接受任意类型的数值,而且在运行过程当中还可以接受其它类型的值
- 因为他有可能会存放任意类型的值,所以说TS他不会对any这种类型做类型检查,这也就意味着,我们仍然可以像在JS一样在他上调用任意的成员,语法上都不会报错
- 但他也还是会存在类型安全的问题,所以我们轻易不要使用这种类型
function string (value: any) {return JSON.stringify(value)
}string('string')
string(100)
隐式类型推断
- 在TS中,如果我们没有通过明确的通过类型注解去标记一个类型,那TS会根据这个变量的使用情况去推断这个变量的类型 — 隐式类型推断
export {}let age = 18// TS会判断为number类型
// age = 'tri' // 报错原因:age已经被判断为number// 这种用法相当于给age添加了 number的类型注解// 无法推断时会将它标记为any,如:
let foofoo = 18;
foo = 'string'
foo = true
- 虽然TS中支持隐式类型判断,而且这种隐式类型推断可以帮我们简化一部分代码,但是我们仍然建议大家尽可能给每一个变量添加明确的类型,这样便于我们后期更直观的理解我们的代码
类型断言
- 在一些特殊形况下TS无法推断出变量的具体类型,而我们作为开发者我们根据代码的使用情况,我们是可以明确知道这个变量到底是什么类型的
// 假定来自一个明确的接口
const nums = [110, 120, 119, 112]const res = nums.find(i => i > 0)
/*** 我们这个时候是明确知道这个返回值一定是一个number的* * 但是TS推断为了number或者undefined* * 那这个返回值就不能作为一个number来使用* * 这时我们可以去断言这个res为一个number类型的* */
- 断言的方式
- 使用as关键词
- 使用<>
const num1 = res as number /** * 此时编译器能明确知道我们的num1是一个number * */ const num2 = <number>res /** * 两者效果一致,但是这种尖括号的方式她有个小问题 * * 当我们在代码当中使用了JSX的时候 * * 这里的<number>会和JSX中的标签产生语法冲突 * * 推荐使用as的方式 * */
- 注意:
- 类型断言并不是类型转换,这里并不是把一个类型转换为了另外一个类型,因为类型转换是代码在运行时的一个概念,我们这个地方类型的断言只是在编译过程中的一个概念,当代码编译过后,断言也就不会存在了
接口
- 可以理解为一种规范或者契约,是一种抽象的概念,可以约定一种对象的结构,我们去使用一个接口就必须要遵循这个接口的全部的约定
- 在TS当中接口最直观的体现就是可以约定一个对象当中具体应该有哪些成员,这些成员的类型又是什么样的
export {}interface Post {/*** 这里可以使用逗号分隔,但是标准是用分号,分号也可以省略* */ title: string;content: string
}function pointPost (post: Post) {console.log(post.title)console.log(post.content)
}
/*** 这个函数对对象有一些要求,必须要title属性和content属性* * 只不过这种要求实际上是隐形的,没有明确的表达* * 这种情况就可以使用接口表现出来约束* */ pointPost({'title': 'hi, TS','content': 'hi'
})
- 一句话总结:接口就是用来约束对象的结构,一个对象去实现一个接口,他就必须要拥有这个接口当中所有的成员
接口补充
- 对于接口中约定的成员还有一些特殊的用法
- 可选成员
- 如果说我们在一个对象当中,我们某一个成员他是可有可无的,我们对于约束这个对象的接口,我们可以使用可选成员这样一个特性
- 这种用法其实就相当于对其类型标记了一个指定类型或者是undefined
interface Post {title: string;content: string;subtitle?: string }const hello:Post = {'title': 'hi, TS','content': 'hi' }
- 只读成员
- 初始化过后就不可再次修改
interface Post {title: string;content: string;subtitle?: string;readonly summary: string }const hello:Post = {'title': 'hi, TS','content': 'hi','summary':'初始化后不可修改' } // hello.summary = 'hhhhhhhh' // 报错
- 动态成员
- 一般适用于一些具有动态成员的对象,例如程序中的缓存对象,他在运行当中就会出现一些动态的键值
interface Cache {[key: string]: string// key是不固定的,string是key的类型注释,外边的string是设置给这个动态属性的值 }const cache: Cache = {}cache.foo = 'value' cache.foo = '123'
- 可选成员
类的基本使用
- Classes
- 描述一类具体事务的抽象特征
- 例如手机就是一个类,特征就是可以接打电话,收发短信,在这个类型下,还会有一些细分的子类,这种子类她一定会满足父类的所有特征,然后多出一些额外的特征,例如智能手机,除了接打电话收发短信,还可以使用一些APP
- 我们是不能直接使用这个类的,而是使用这个类的具体事务,比如你手上的智能手机
- 类也是一样的,它可以用来描述一类具体对象的抽象成员,在ES6以前,JS都是通过 函数+原型 模拟实现的类,ES6之后JS就有了专门的class
- 在TS中,除了可以使用所有ES标准当中所用类的功能,还添加了一些额外的功能与用法,例如对类成员有特殊的访问修饰符,还有一些抽象类的概念
class Person {/*** 在TS中,类的属性必须要有一个初始值可以在 = 后边赋值* * 也可以在构造函数中初始化* * 两者必须有其中一个* */ name: string // = '初始值'age: number // = 123constructor (name: string, age: number) {/*** 我们在TS中我们需要明确在类型当中去声明他所拥有的一些属性* * 而不是直接在构造函数当中动态通过this添加* */ this.name = namethis.age = age}
}
- 类的属性在使用之前,必须要先在类型中去声明,目的其实就是为了给我们的属性去做一些类型的标注,除此之外,我们可以按照ES6当中的语法为这个类去声明一些方法
类的访问修饰符
- private — 标注为私有属性,只能在类的内部访问到
export {}class Person {name: stringprivate age: number // 标注为私有属性,只能在类的内部访问到constructor (name: string, age: number) {this.name = namethis.age = age}
}const tom = new Person('tom', 18)
console.log(tom.name)
// console.log(tom.age) // 报错
- public — 标注为公有成员,TS中为默认!
export {}class Person {...private age: number // 标注为私有属性,只能在类的内部访问到...
}const tom = new Person('tom', 18)
// console.log(tom.age) // 报错
- protected — 受保护的,外部访问不到
export {}class Person {...protected gender: boolean...
}const tom = new Person('tom', 18)
console.log(tom.gender) // 报错,不能在外部被访问到
-
private 与 protected 区别
- protected只允许在此类当中去访问对应的成员
export {}class Person {public name: string // 标注为公有成员,TS中为默认!private age: number // 标注为私有属性,只能在类的内部访问到protected gender: booleanconstructor (name: string, age: number) {this.name = namethis.age = agethis.gender = true} }class Student extends Person {constructor(naem: string, age: number) {super(name, age)console.log(this.gender) // 可以访问到} }
-
作用:
- 控制一些类当中成员的可访问级别
-
注意点:
- 对于构造函数的访问修饰符默认是public,如果设置为private,这个类型就不能在外部被实例化,也不能被继承,这种情况我们就只能在这个类的内部去添加一个静态方法,然后在静态方法中去创建这个类型的实例,因为private只允许在内部去访问
class Student extends Person {private constructor(naem: string, age: number) {super(name, age)console.log(this.gender) // 可以访问到}static create (name: string, age: number) {return new Student(name, age)} } // const jack = new Student() const jacked = Student.create('jack', 18)
- 如果把构造函数当中的类型标记为protected,这样一个类型也是不能够在外部被实例化的,但是相比于private,他是允许被继承的
类的只读属性
export {}class Person {public name: string private age: number protected readonly gender: booleanconstructor (name: string, age: number) {this.name = namethis.age = agethis.gender = true}sayHi (msg: string): void {console.log(`我是${this.name},${msg}`)}
}const tom = new Person('tom', 18)
console.log(tom.name)
tom.gender = false
类与接口
- 相比于类,接口的概念要更抽象一点
- 我们接着拿之前手机的例子来去作对比,那我们说手机是一个类型,这个类型的实例都是可以接打电话收发短信,因为手机这个类的特征就是这样,但是我们能够打电话的不仅只有手机,之前还有座机也可以打电话,但是座机并不属于手机这个类目,而是个单独的类目,因为他不能收发短信,在这种情况下,就会出现不同的类与类之间出现共同的特征,对于这些公共的特征,我们一般会使用接口去抽象,手机可以理解为,手机也能接打电话,因为它实现了这个协议,座机也可以打电话,因为他也实现了这个协议,这里说的协议,程序当中就叫做接口
export {}interface Eat {eat (food: string): void
}interface Run {run (distance: number): void
}class Person implements Eat, Run {eat (food: string): void {console.log(`优雅的进餐:${food}`)}run (distance: number): void {console.log(`直立行走:${distance}`)}
}class Animal implements Eat, Run {eat (food: string): void {console.log(`呼噜呼噜的吃:${food}`)}run (distance: number): void {console.log(`爬行:${distance}`)}
}
抽象类
- 某种程度上和接口有点类似,它也可以用来去约束子类当中必须要有某一个成员
- 抽象类它可以包含一些具体的实现,而接口只能是成员的一个抽象,不包含具体的实现
- 一般比较大的类目比较建议使用抽象类,例如刚才的动物类,其实他就应该是抽象的,因为我们所说的动物只是一个泛指,并不够具体,在他的下边一定会有一些更细化的分类
abstract class Animal {eat (food: string): void {console.log(`呼噜呼噜的吃:${food}`)}abstract run (distance: number): void
}// 被定义为抽象类过后,他就只能够被继承,不能够再使用new的方式去实例class Dog extends Animal {run (distance: number): void {console.log('四角爬行',distance)}
}const d = new Dog()
d.eat('狗')
d.run(100)
泛型
- 定义函数,接口,或者类的时候,我们没有去指定具体的类型,等到我们使用的时候,再去指定具体的类型的一个特征
- 以函数为例,泛型就是我们在声明这个函数时,不去指定具体的类型,等到调用时传递一个具体的类型,目的是为了最大程度的复用我们的代码
export {}// 创建一个指定长度的数组
// function createNumberArray (length: number, value: number): number[] {
// const arr = Array<number>(length).fill(value)
// return arr
// }// const res = createNumberArray(3, 100)function createArray<T> (length: number, value: T): T[] {const arr = Array<T>(length).fill(value)return arr
}const res = createArray<number>(3, 100)
const res1 = createArray<string>(3, '100')
- 总结:
- 泛型其实就是把我们定义时不能够明确的类型,改为一个参数,让我们在使用的时候再去传递
类型声明
- 实际的项目开发中,我们肯定会用到一些第三方的npm模块,而这些模块并不是一定通过TS编写的,所以它所提供的成员就不会有强类型的体验
- 说白了就是一个成员在定义的时候因为某种原因导致没有明确的类型,然后我们使用时再为他单独做出一个明确的声明,这种用法存在的原因就是为了考虑兼容一些普通的JS模块,由于TS的社区非常的强大,目前绝大多数常用的npm模块都已经提供了对应的声明,我们只需要安装一下它所对应的类型声明模块即可
- 如果没有对应的声明,我们就只能通过declare语句去声明所对应的模块类型
import {camelCase} from 'lodash' declare function camelCase (input: string): stringconst res = camelCase('hello typed')
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 转正总结
到了十一月初终于是到了转正的时候啦 这三个月试用期期间,不仅修改和增加了大量的功能,还有增加了3个大的模块,算是做了一些实实在在的事情。 来这里发现其实很多都是组件化的东西,组件确实好用,所有的页面并不需要大量…...
2024/4/21 15:05:03 - 我做技术面试官的一些体会
作为一个一年多的前端工程师,之前的前端老大离职后,自己就扛起了一些前端方面的事务。面试当然是最具挑战的事情了,首先是筛选简历,接着是邀请到公司面对面聊。说说自己的体会吧。 筛选简历: 偏实习和经验较少的求职者…...
2024/4/21 15:05:02 - vue开发微信商城项目总结之六--关于vuex的思考
先对项目进行一下简单的介绍 vue开发微信商城项目总结之一–项目介绍 项目开发初期,由于项目比较着急上线,前端的框架在选型上比较仓促,只是因为vue学习成本较低,就选了它,没有什么别的原因, 之前看过angul…...
2024/4/21 15:05:01 - 一位老程序员的心得分享,WEB前端菜鸟,感觉很迷茫,该怎么做?
我们可以把学习路线比作游戏中的段位上分,在不同的分段都有自己的定位和要锻炼的事情: 1、青铜 - 从零开始小学生:怀着满腔的热血,看到了这一个行业的希望和未来,准备开始学习 Web 开发知识。 a. 先通过 w3cschool 等…...
2024/4/21 15:05:00 - 浅谈C++中句柄的使用
我想在此将我新学的句柄类做个小结,就我个人理解,C++句柄类的主要目的是在对象层面上实现多态。 比如: Class A { public: A(){} ~A(){} virtual void func(){printf("A";} }; Class B:public A { public: B(){} ~B(){} void func(){printf("B";} };假设…...
2024/4/21 15:04:59 - 初学前端小白,如何撕去菜鸟标签,这些学习经验绝对让你受益匪浅!
作为前端新人,我们常以菜鸟自居,主要是专业程度不高,还有就是自谦。其实,作为菜鸟的我们也想撕掉这类标签,我们也努力,可还是学不好前端,是真的不适合做这行还是方法不对,没人告诉我…...
2024/4/25 22:41:58 - 在ASP.NET Core MVC中搭建基于TypeScript的Angular2项目
这是本人的第一篇博客。 我是一名比较喜欢追求新技术的野生程序员,技术水平有限,只是想记录和分享一些个人心得体会,文章中若有不正确之处,请海涵! 前言 对于一个没有学过TypeScript,不了解ES5、Node.Js的初…...
2024/4/21 15:04:57 - 作为面试官之后的一些体会
作为一个一年多的前端,之前的前端老大离职后,自己就扛起了一些前端方面的事务。 面试当然是最具挑战的事情了,首先是筛选简历,接着是邀请到公司面对面聊。 说说自己的体会吧。 筛选简历: 偏实习和经验较少的求职者&…...
2024/4/25 16:57:42 - web前端开发学习总结-1
正式开始学习前端开发,以前就会写简单的html,js,现在回来一看,内容实在太丰富了,基本要从基础学起。 努力。。。努力。。。 学前端,首先要选个前端框架,VUE,Angular,Rea…...
2024/4/21 15:04:56 - 【21】总结一年来的前端学习心得
到今天,前端学习刚好满一年。我也顺利从机械狗变成一枚前端狗。对于前端学习,自己也是摸着石头过河,中间也有过困惑和迷茫。本文主要讲述自己一年来对于前端学习的心得体会,希望能对学习前端的人提供一些帮助。 前端主要分为三部…...
2024/4/21 15:04:54 - 三角形问题 -软件测试
UI版 : 三角形问题(JFrame界面) - 软件测试 一. 软件设计介绍 该软件以研究三角形问题为目的.通过用户选择三角形判断依据后,输入三角形的三条边长,通过相对应的功能判断出该三角形的类型.当用户完成本次操作后,会提示是否继续操作.若退出操作即结束该程序.二. 软件开发平台简介…...
2024/4/20 15:07:08 - LDAP ObjectClass 详解 (转)
初学LDAP时关于objectClass和Attribute之间的关系总是困扰着我,找过许多的中文资料都没有得到答案。最近终于彻底弄明白了这个问题,决定记录下来,以让后学者少走弯路。非常奇妙的是他们之间的关系与Java里面的一些概念很相似,接下来我会结合Java来讲讲LDAP中的objectClass与…...
2024/4/28 16:54:24 - 在线电影订票系统 - Vue学习心得
在最近电影订票系统的实现中,使用了Vue.js作为前端开发框架。 介绍 Vue是一个极简的Javascript MVVM框架。它容易上手,便于整合。而且,它对于Web组件化开发的思考和设计,使其完全能够为复杂的SPA(单页应用࿰…...
2024/5/5 9:04:52 - 上海切开双眼皮美莱保
...
2024/4/20 15:07:05 - 信息系统项目管理师2019年上半年上午试题解析(二)
21.基于买方的购买历史及行为分析,进行针对性的广告推送,属于( )的典型应用。 A.大数据 B.云计算 C.物联网 D.智慧城市 参考答案:A 参考解析: •大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的…...
2024/5/5 8:55:30 - ssm框架搭建maven工程实现上传图片功能和选择、展示
网站前台分析 1.1网站前台有哪些页面 网站首页商家(店铺)首页商品详细页商品搜索页购物车列表页购物选项选择页支付页用户注册页用户登陆页用户中心页等 1.2网站首页广告 首页海报(轮播图)今日推荐猜你喜欢楼层广告 1.3数据库表…...
2024/5/5 6:34:07 - 无代码编程
中台之后,便无代码。 规模化的组织,经常要面临这样的挑战:每个应用的基础设施是相同的,部分的代码也是相同的,甚至于它们可能只是数据模型不同而已。结果却导致了,他/她们要一次又一次地重新编写一个应用。…...
2024/4/21 15:04:51 - 利于前台开发的两大工具flex和vue
1 简介 今次给大家安利的这两种工具,flex当为页面显示布局中很强大的一个属性,属于css范畴. 而vue则属于一种js插件,其作用在于将页面显示与js数据近乎完美的完全区分开,而又使两者遥相控制(当然主要是js数据控制页面显示). 2 flex 1.背景 谈到页面布局,我想很多人都曾经遇到过…...
2024/4/21 15:04:50 - web框架之Vue渐进式框架-安装及入门
1 vue: js渐进式框架 2 优点: 单页面、轻量级、数据驱动、数据双向绑定、虚拟DOM、组件化开发(页面代码的服用) 3 vue实例成员: el(挂载点)、data(数据)、methods(方法) 4 vue指令:v-text(纯文本指令)、v-html(可以解析…...
2024/4/21 15:04:50 - “菁英汇项目”(angular)个人总结,以及经验总结
整个项目下来,真正开发时间没有十天,两个前端一个负责后台,一个负责前台。开会的时候自告奋勇了,说要做前台,感觉更有挑战些。这是我的第一个angular项目,做起来非常的顺利。 一、浏览器的兼容性bug总结 1.…...
2024/4/21 15:04:48
最新文章
- 排序算法之希尔排序(缩小增量排序)
希尔排序是插入排序的优化,如果不了解插入排序可以看排序算法之插入排序-CSDN博客这篇博客,希尔排序算法通过对原始数据集使用 gap 分组的方法,先将数据分组进行插入排序,随着排序的进行,逐渐减小 gap 的值,…...
2024/5/7 20:44:37 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/7 10:36:02 - 学习鸿蒙基础(11)
目录 一、Navigation容器 二、web组件 三、video视频组件 四、动画 1、属性动画 .animation() 2、 转场动画 transition() 配合animateTo() 3、页面间转场动画 一、Navigation容器 Navigation组件一般作为页面的根容器,包括单页面、分栏和自适应三种显示模式…...
2024/5/4 11:54:31 - git总结
建议配合gitlab实操 git分区:工作区(修改的地方),暂存区(add),本地仓库(commit) 常用命令 初次使用配置 git config --global user.name "xxx" git config --global user.email "xxxqq.com" 这2个是针对整个主机的全局…...
2024/5/7 8:56:04 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/7 5:50:09 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/7 9:45:25 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/7 14:25:14 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/7 11:36:39 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/7 9:26:26 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/6 21:42:42 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57