这是我参与「第五届青训营」伴学笔记创作活动的第 10 天
Object与object{} -- 加餐环节
前置知识点补充
| 原始数据类型(基础数据类型) | 中文称呼 | 引用数据类型 | 中文称呼 |
|---|---|---|---|
| Undefined | 未定义 | {} | 对象 |
| Null | 空值 | function | 函数 |
| Boolean | 布尔值 | [] | 数组 |
| Number | 数字 | ||
| String | 字符串 |
存储位置不同
原始数据类型:直接存储在栈(stack)中的简单数据段,占据空间小,大小固定,属于被频繁使用的数据,所以存储在栈中;
引用数据类型:存储在堆(heap)中的对象,占据空间大,大小不固定,如果存储在栈中,将会影响程序运行的性能。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后,从堆中获得实体。
传值方式不同
- 基本数据类型:按值传递
不可变 (immutable) 性质:
基本类型是不可变的 (immutable),只有对象是可变的 (mutable). 有时我们会尝试 “改变” 字符串的内容,但在 JS 中,任何看似对 string 值的 "修改" 操作,实际都是创建新的 string 值。任何方法都无法改变一个基本类型的值(在下面的字面量类型中会再次强调)
- 引用类型:按引用传递
引用类型的值是可变的
引用类型的值是同时保存在栈内存和堆内存中的对象。javascript 和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢? 实际上,是操作对象的引用,引用类型的值是按引用访问的。
object、Object以及{} 这三个类型(第三个类型为空对象字面量模式)大家可能不太理解这集加餐环节就是进行补充,一个冷门但是不邪门的知识点
Object类型
//这个类型是跟原型链有关的原型链顶层就是 Object,所以值类型和引用类型最终都指向 Object,所以在TypeScript中Object他包含所有类型。就可以等于任何一个值
//1.数字类型
let a:Object = 123
//字符串类型
let b:Object = "张三今天没穿裤子"
//数组类型
let c:Object = [1314,520]
//对象类型
let d:Object = {name:"草莓",sex:"女",address:"张三微信一群"}
//any或者function
let e:Object = ()=> "学姐贴贴"
Object 类型是所有 Object 类的实例的类型。 由以下两个接口来定义:
Object接口定义了Object.prototype原型对象上的属性;ObjectConstructor接口定义了 Object 类的属性, 如上面提到的Object.create()。
object类型
object 代表所有非值类型(非原始类型)的类型,例如 数组 对象 函数等,常用于泛型约束
所有原始类型都不支持,所有引用类型都支持
//错误 原始类型(字符串)
let f:object = '努力会获得回报的'
//错误 原始类型(数字)
let g:object = 123
//错误 原始类型(布尔值类型)
let h:object = true
//正确 引用类型(数组类型)
let i:object = [123,"学姐学习Vue3",true]
//正确 引用类型(对象类型)
let j:object = {name:"张三",identity:['B站UP主','二次元','京东员工','全栈开发工程师'],sex:"女"}
//正确 引用类型(函数类型)
let k:object = ()=>"不要对自己pua,相信自己是最棒的,尊重自己,人生更精彩"
{}字面量类型
看起来很别扭的一个东西 你可以把他理解成 new Object 就和我们的第一个 Object 基本一样 包含所有类型
//与Object类型一样
let l:{} = 123//等等,就不写了,跟Object一样
//补充--字面量模式
//这个虽然可以赋值任意类型,赋值结束后,是没办法进行一个修改和增加的操作的
数组类型(TS -- 4)
普通的声明方式
//类型加中括号
let arr:number[] = [123]
//这样会报错定义了数字类型出现字符串是不允许的
let arr:number[] = [1,2,3,'1']
//操作方法添加也是不允许的
let arr:number[] = [1,2,3,]
let arr:number[] = [1,2,3,4];//数字类型的数组
let arr2:string[] = ["1","2","3","4"];//字符串类型的数组
let arr3:any[] = [1,"2",true,undefined,[],{}];//任意类型的数组
let arr4:number[][][] = [[[]],[[]],[[]]]
//这个也能够决定你二维数组还是三维数组想要套几层就写几层
泛型 -- Array <类型>
规则 Array <类型>
let arr1:Array<number> = [1,2,3,4,5]
let arr2:Array<string> = ["1,2,3,4,5"]
let arr3:Array<boolean> = [true]
//泛型数组套娃写法(还能够决定数组里面数组的类型之类的)
let arr4:Array<Array<number>> = [[123],[456]]
类数组 -- arguments
是所有参数的一个集合
function Arr(...args:any):void{//...args为ES6的解构方式,任意类型,voidwei不能有返回值
console.log(arguments)//输出{'0':4,'1':56,'2':789}
let arr:number[] = arguments//会报错,报缺少类型number[]的以下属性:pop,push,concat,join
let arr:IArguments = arguments//解决方法
//其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}
Arr(4,56,789)
接口表示数组
一般用来描述类数组
interface ArrNumber {
[index: number]: number;//后面的才是定义类型的
//[index: number]: string;这个就是定义字符串的了
}
let Arr: ArrNumber = [1, 2, 3, 4, 5];
//let Arr: ArrNumber = ["1, 2, 3, 4, 5"];
//表示:只要索引的类型是数字时,那么值的类型必须是数字。
函数扩展(TS -- 5)
函数内参数类型也是可以定义的
const fn(name:string,age:number):string{
return name + age
}
let a = fn('张三',10000)//输入不符合上述参数内定义的类型就会出错
console.log(a)//输出张三10000
--------------------------------------------------------------------
const fn(name:string,age:number = 666):string{//如果在下面使用的时候,没有参数传进来就会以你在这里设置的默认参数执行,比如这个666
return name + age
}
let a = fn('张三')//输入不符合上述参数内定义的类型就会出错
console.log(a)//输出张三666
--------------------------------------------------------------------
const fn(name:string,age?:number = 666):string{//也可以使用这个`?`操作符,age传不传就变成可选的了
return name + age
}
let a = fn('张三穿女仆装')//输入不符合上述参数内定义的类型就会出错
console.log(a)//输出张三穿女仆装
对象形式的定义
跟定义对象差不多,但是在针对多个参数的时候会更加的方便,且记得引用的时候要写成({xxxx})形式,不然会报错,输出的是数组形式的
interface User{
name:string;
age:number
}
const fn(user:User):User{//这里的参数填写方式就变得简单了
return user
}
let a = fn({
name:"'张三",
age:18
})//输入不符合上述参数内定义的类型就会出错
console.log(a)//输出{name:'张三',age:18}
函数重载
重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。
如果参数类型不同,则参数类型应设置为 any。
参数数量不同你可以将不同的参数设置为可选。
为了让编译器能够选择正确的检查类型,它与 JavaScript 里的处理流程相似。 它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
function fn(params:number):void//第一套规则
function fn(params:string,params2:number):void//第二套规则
function fn(params:any,params?:any):void{
console.log(params)
console.log(params2)
}
let a = fn(1,1)
//输出1跟undefined,因为遵循的是第一套规则
let a = fn("1",1)
//输出"1"跟1,遵循的是第二套规则