五一之后第一周(5.6-5.9)的安排
- type 和 interface 区别
- webpack中的externals配置使用
- https和http协议的区别
ts运行,本地tslint提示的各种报错有时真让人抓狂!!!(持续完善当中)
序列 | 提示 | 描述 |
---|---|---|
1 | Exceeds maximum line length of 150 | 单行超150字符 |
2 | expected an assignment or function call | expected an assignment or function call |
3 | comment must start with a space | // 注释应以空格开头 |
4 | for (… in …) statements must be filtered with an if statement | for in 循环体内应有if判断属性是否存在 |
5 | Declaration of instance field not allowed after declaration of instance method. Instead, this should come at the beginning of the class/interface. | class/interface的属性定义应放在方法前 |
6 | Declaration of static method not allowed after declaration of instance method. Instead, this should come after instance fields. | class/interface的静态方法定义应放在非静态方法前 |
7 | Shadowed variable | 变量名重名 |
8 | Missing radix parameter | parseInt缺少转换基数,直接第二个参数为0即可 |
9 | Class name must be in pascal case | class类命名必须首字母大写 |
10 | file should end with a newline | 文件末尾少个空行 |
11 | Type ‘string’ is not assignable to type ‘number’ | 接口规定的是number类型不是字符串类型 |
ts中的type和interface区别
interface 和 type interface 和 type 都可以用来定义一些复杂的类型结构,最很多情况下是通用的,最初我一直没能理解它们二者之间区别在哪里,后来发现,二者的区别在于:
- type 不能像 interface 那样合并,其在作用域内唯一
- interface创建了一种新的类型,而 type 仅仅是别名,是一种引用;
- 如果 type 使用了 union operator (|) 操作符,则不能将 type implements 到 class 上;
- 如果 type 使用了 union(|) 操作符 ,则不能被用以 extends interface
interface阔以,type不行
可选属性
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。
- 优点一是可以对可能存在的属性进行预定义
- 优点二是可以捕获引用了不存在的属性时的错误
1
2
3
4
interface Chart {
Num: number;
Type?: string[];只读属性
初次创建的时候赋值,其他时候不允许再次赋值,在属性前用readonly
指定1
2
3
4interface Point {
readonly x: number;
readonly y: number;
}额外属性检查
当你不确定接口会有哪些其他的属性的时候,阔以用一个字符串
索引签名1
2
3
4
5interface Point {
readonly x: number;
readonly y: number;
[propName: string]: any
}Declaration merging, type 不能像 interface 那样合并
接口阔以定义多次,而类型别名则不行1
2
3
4
5
6interface data {
x: number
}
interface data {
y: number
}函数类型
这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口。 下例展示了如何创建一个函数类型的变量,并将一个同类型的函数赋值给这个变量。1
2
3interface SearchFunc {
(source: string, subString: string): boolean;
}对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配,这样也想1
2
3
4
5let serF: SearchFunc
serF = function(source: string, subString: string) {
let result = source.search(subString);
return result > -1;
}1
2
3
4
5let serF: SearchFunc
serF = function(sou: string, sub: string) {
let result = sou.search(sub);
return result > -1;
}可索引类型
索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。上面例子里,我们定义了dataArray接口,它具有索引签名。 这个索引签名表示了当用1
2
3
4
5
6
7interface dataArray {
[index: number]: string
}
let arr:dataArray = [
'chen',
'peng'
]number
去索引dataArray时会得到string类型的返回值。TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。
1
2
3
4
5interface NumberDictionary {
[index: string]: number;
length: number; // 可以,length是number类型
name: string // 错误,`name`的类型与索引类型返回值的类型不匹配
}
类类型
- 实现接口
TypeScript也能够用它来明确的强制一个类去符合某种契约,用implements
实现接口1
2
3
4
5
6
7
8
9
10
11
12interface ClockInterface {
currentTime: Date;
setTime(d: Date); // 在接口中描述一个方法,在类里实现它,如同下面的setTime方法一样:
}
class Clock implements ClockInterface {
currentTime: Date;
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) { }
} - 类静态部分与实例部分的区别
当你操作类和接口的时候,你要知道类是具有两个类型的:静态部分的类型和实例的类型。 你会注意到,当你用构造器签名(new )去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误:
这里因为当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。
1 | // 只对其实例部分进行类型检查 |
因此,我们应该直接操作类的静态部分。 看下面的例子,我们定义了两个接口, ClockConstructor为构造函数所用和ClockInterface为实例方法所用。 为了方便我们定义一个构造函数 createClock,它用传入的类型创建实例。
1 | // 构造函数所用,这里用interface会报错?类的静态部分 |
因为createPerson的第一个参数是PerConstructo类型,在createPerson(P1Type, 7, 32)里,会检查P1Type是否符合构造函数签名。
访问修饰符:private、public、protected
- 默认为public,public规定的属性必须在类的顶层
- 当成员被标记为private时,它就不能在声明它的类的外部访问
- protected和private类似,但是,protected成员在派生类(子类)中可以访问。这是protected和privat最大的区别
1 |
|
这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里,Clock是一个 派生类,它派生自 ClockParent 基类,通过 extends关键字。 派生类通常被称作子类,基类通常被称作超类。
派生类包含了一个构造函数,它 必须调用 super(),它会执行基类的构造函数。 而且,在构造函数里访问 this的属性之前,我们 一定要调用 super()。 这个是TypeScript强制执行的一条重要规则。
一个ts文件不能同时定义2个及以上的类?添加tslint.json中的规则即可
1 | "rules": { |
继承接口
和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。主要type类型别名,也阔以继承,语法稍有不同
1 | interface Shape { |
也阔以继承多个接口
1 | interface Shape { |
关键字implements
有什么作用?
一句话即: 约束接口按照某种契约,举例说明
1 | // implements的实现 |
接口中ClockInter约束了age必须是数字类型,所以在通过ClockInter实现Clock这个类的时候,age必须按照接口定义的来约束。
如何引用这个Clock
这个类呢,在vue文件直接import导入,然后new调用即可,如
1 | import { Clock } from '../../utils/implementsd2' |
Type类型别名
type 会给一个类型起个新名字。 type 有时和 interface 很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型
1 | // 构造函数所用,这里用interface会报错? |
起别名不会新建一个类型 - 它创建了一个新名字
来引用那个类型。给基本类型起别名通常没什么用,尽管可以做为文档的一种形式使用。
interface vs type
两者都可以用来描述对象或函数的类型,但是语法不同
1
2
3
4type SetPoint = (x: number, y: number) => void;
interface SetPoint {
(x: number, y: number): void;
}与接口不同,类型别名还可以用于其他类型,如基本类型(原始值)、联合类型、元组。
1
2
3
4
5
6// tuple
type Data = [number, string];
// dom
let div = document.createElement('div');
type B = typeof div;继承Extend
语法有所不同,interface继承用extends,type用 & 继承1
2type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };class implements实现接口
类可以以相同的方式实现接口或类型别名。但是请注意,类和接口被认为是静态的。因此,它们不能实现/扩展命名联合类型的类型别名。1
2
3
4
5
6
7type PartialPoint = { x: number; } | { y: number; };
// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
x: 1;
y: 2;
}declaration mergeing
与类型别名不同,接口可以定义多次,并将被视为单个接口(合并所有声明的成员)
- 计算属性,生成映射类型
type 能使用 in 关键字生成映射类型,但 interface 不行。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type Keys = "firstname" | "surname"
type DudeType = {
[key in Keys]: string
}
const test: DudeType = {
firstname: "Pawel",
surname: "Grzybek"
}
// 报错
//interface DudeType2 {
// [key in keys]: string
//}
参考链接
webpack中的externals配置使用
官网解释
webpack 中的 externals 配置提供了不从 bundle 中引用依赖的方式。解决的是,所创建的 bundle 依赖于那些存在于用户环境(consumer environment)中的依赖。
意思是如果需要引用一个库,但是又不想让webpack打包(减少打包的时间),并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用(一般都以import方式引用使用),那就可以通过配置externals;
Vue项目中如何实践
- 在vue.config.js中更改
1
2
3
4
5
6
7
8
9
10
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.externals = {
echarts: 'echarts',
}
}
}
} - 在index.html中引入vue.js,通过cdn方式或者本地资源引入都行
externals和libraryTarget的关系
- libraryTarget配置如何暴露 library。如果不设置library,那这个library就不暴露。就相当于一个自执行函数
- externals是决定的是以哪种模式去加载所引入的额外的包
- libraryTarget决定了你的library运行在哪个环境,哪个环境也就决定了你哪种模式去加载所引入的额外的包。也就是说,externals应该和libraryTarget保持一致。library运行在浏览器中的,你设置externals的模式为commonjs,那代码肯定就运行不了了。
- 如果是应用程序开发,一般是运行在浏览器环境libraryTarget可以不设置,externals默认的模式是global,也就是以全局变量的模式加载所引入外部的库。
参考链接
https和http协议的区别
HTTP和HTTPS的基本概念
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,是http协议身披一层SSL(Secure Socket Layer,安全套阶 层)协议,SSL这层协议存在于应用层(http层)到TCP层之间:
应用层(http) => ssl => TCP => IP
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
HTTP缺点
- 明文传输,私密信息已被窃取
- 无法验证通信者身份,可能存储伪装者(客户端和服务器)
- http协议无法判断通信报文的完整性,通信报文在TCP/IP协议通信中可能会被篡改
http协议的缺点,只能是ssl协议来完成
HTTPS使用SSL(Secure Scocket Layer ,安全套阶层)和TLS(Transport Layer Secure,安全层传输协议)这两种协议。
IETF 以 SSL3.0 为基准,后又制定了 TLS1.0、TLS1.1 和TLS1.2。TSL 是以 SSL 为原型开发的协议,有时会统一称该协议 为 SSL。当前主流的版本是 SSL3.0 和 TLS1.0。由于 SSL1.0 协议在设计之初被发现出了问题,就没有实际投入 使用。SSL2.0 也被发现存在问题,所以很多浏览器直接废除了 该协议版本。
HTTP + 认证 + 加密 + 完整性保护 = HTTPS
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl(Secure Scocket Layer 安全套阶层)加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者默认是80,后者默认是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTPS优点
- seo方面
采用https的网站在搜索结果的排名中较高 - 安全性
1.使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
2.TTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
3.HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
HTTPS缺点
seo方面
使用HTTPS协议会使页面的加载时间延长近50%,增加10%到20%的耗电,此外,HTTPS协议还会影响缓存,增加数据开销和功耗,甚至已有安全措施也会受到影响也会因此而受到影响经济方面
1.ca证书需要费用
2.ssl证书需要绑定ip,不能在同一个IP上绑定多个域名
3.https连接缓存不如http高效,大流量网站不一定非要https
4.HTTPS连接服务器端资源占用高很多,支持访客稍多的网站需要投入更大的成本
- 使用ssl协议,处理速度会变得很慢
一种是指通信慢。另一种是指由于大量消耗CPU 及内存等资源,导致处理速度变慢。
由于https还需要做服务器/客户端加密以及解密处理,因此肯定会消耗CPU和内存等硬件资源。
参考链接