前言

最开始的时候写ts的时候遇到过这种问题,为什么String类型不能赋值给string类型,他们不都是字符串吗?在js中不是万物皆对象吗?同类型为什么不可以?

const a: string = "a";
const b: String = a;
const c: string = b;

可以看到string类型可以赋值给String,而String类型不能赋值给string

解惑

在JavaScript中,StringNumber这种被称为包装器,你可以理解为他是一个类或者是构造函数,它返回的是一个对象,而string是一个字面量,被称为原始数据类型

原始数据类型(Primitive data types)有以下:

类型例子描述
number1, -33, 2.5任意数字
string‘hi’, “hi”, hi任意字符串
booleantrue、false布尔值true或false
nullnull值只能为null
undefinedundefined值只能为undefined
字面量1,“1”,“hi”限制变量的值就是该字面量的值
any*任意类型
unknown*类型安全的any,unknown类型的变量不能直接赋值给其他变量。只能赋值给 any 类型和unknown类型。
void空值(undefined)没有值(或undefined)
never没有值不能是任何值
object{name:‘孙悟空’}任意的JS对象
array[1,2,3]任意JS数组
tuple[4,5]元组,TS新增类型,固定长度数组
enumenum{A, B}枚举,TS中新增类型
机翻佬会将原始数据类型Primitives翻译成:基元类型。

而以大写字母开头的,被称为对象数据类型。

常见的对象数据类型(Object data types)如下:

类型例子描述
Objectlet obj: Object = {}最基础的对象类型,几乎所有的JavaScript对象都是Object类型
Arraylet arr: Array<number> = [1, 2, 3]表示一个元素类型固定的数组
Datelet date: Date = new Date()代表日期
RegExplet reg: RegExp = /^abc$/代表一个正则表达式
Promiselet prom: Promise<any> = Promise.resolve()代表一个处理异步操作的对象
Maplet map: Map<number, string> = new Map()含有键和值对的集合
Setlet set: Set<number> = new Set()含有互不重复的值的集合
Functionlet func: Function = () => {}表示一个函数
Classclass MyClass { } let cls: MyClass = new MyClass()表示一个类,是自定义对象类型的一个重要方式
Interfaceinterface IMyInterface { a: number } let inter: IMyInterface = { a: 1 }不是真正的对象, 但在TypeScript中常常被当作类型来使用,作为对象形状的描述

此时我们可能还是不清楚他们之间的区别,下面来写个例子:

const a: string = "a";

a.xxx = "xxx";  // Uncaught TypeError: Cannot create property 'xxx' on string 'a'
const b: String = new String("b");
b.xxx  =  "xxx";

console.log(b.xxx);  // "xxx"

例子说明string是一个字面量值类型,它不像String类型,是一个对象,因为只有对象我们才可以自定义属性,而字面量不可以。

至于为什么我们可以调用字符对象的方法:

const a: string = "a";

console.log(a.length); // 1

是因为js会做隐式转换,将"a"转为String对象,然后调用length,调用结束后又将对象变回"a"

这系列操作被称为:装箱和拆箱,正因为这个操作,小写的string可以赋值给大写的String,反之却不可以,因为String对象的原始值必须通过String.toString()方法获取(不同对象获取方法不同,如:xxx.valueOf())。

而且这个例子也证明,在js中并不是万物皆对象。

此时你应该就可以明白小写类型和大写类型的区别了。

在ts中官方推荐是使用小写类型,大写是特殊情况,如无必要,不要使用。

特殊的object和Object

小写的object是除了numberstringbooleansymbolnullundefined之外的类型,是更加具体的值,而大写的Object在JavaScript中是所有对象的基类,它可接受的类型就会比小写的object更广一些。

const a: object = "a";

const b: Object = "a";

可以看到string类型无法赋值给object,但是可以赋值给Object类型,因为装箱操作,字符串被转换为String对象,而Object又是它的基类,那么自然可以赋值给Object了。

分类: TypeScript 标签: 对象类型小写类型大写类型装箱拆箱原始类型

评论

全部评论 3

  1. lzan13
    lzan13
    Google Chrome Windows 10
    真的是通俗易懂,解惑了[doge]
  2. Dabenshi
    Dabenshi
    Google Chrome Windows 10
    简单透彻[支持]
    1. 木灵鱼儿
      木灵鱼儿
      FireFox Windows 10
      @Dabenshi[脱单doge]美汁汁

目录