mortal-cultivation-biography / daydayup

A FE interview-questions collection repo.
8 stars 0 forks source link

ts 中 object/Object/{} 区别 #96

Open nmsn opened 1 year ago

nmsn commented 1 year ago
foo: object
bar: {}
baz: Object
nmsn commented 1 year ago

object

ts 2.2 引入 object 用来表示非原始类型

// All primitive types
type Primitive = string 
 | boolean | number 
 | bigint | symbol 
 | null | undefined;

// All non-primitive types
type NonPrimitive = object;

小写的 object 类型代表 JavaScript 里面的狭义对象,即可以用字面量表示的对象,只包含对象、数组和函数,不包括原始类型的值。

let obj:object;

obj = { foo: 123 };
obj = [1, 2];
obj = (a:number) => a + 1;
obj = true; // 报错
obj = 'hi'; // 报错
obj = 1; // 报错

Object

大写的Object类型代表 JavaScript 语言里面的广义对象。所有可以转成对象的值,都是Object类型,这囊括了几乎所有的值。

let obj:Object;

obj = true;
obj = 'hi';
obj = 1;
obj = { foo: 123 };
obj = [1, 2];
obj = (a:number) => a + 1;

上面示例中,原始类型值、对象、数组、函数都是合法的Object类型。

事实上,除了undefined和null这两个值不能转为对象,其他任何值都可以赋值给Object类型。

let obj:Object;

obj = undefined; // 报错
obj = null; // 报错

Object 是所有 Object 类的实例的类型。由以下两个接口定义:

// node_modules/typescript/lib/lib.es5.d.ts

interface Object {
  constructor: Function;
  toString(): string;
  toLocaleString(): string;
  valueOf(): Object;
  hasOwnProperty(v: PropertyKey): boolean;
  isPrototypeOf(v: Object): boolean;
  propertyIsEnumerable(v: PropertyKey): boolean;
}

// node_modules/typescript/lib/lib.es5.d.ts

interface ObjectConstructor {
  /** Invocation via `new` */
  new(value?: any): Object;
  /** Invocation via function calls */
  (value?: any): any;

  readonly prototype: Object;

  getPrototypeOf(o: any): any;

  // ···
}

declare var Object: ObjectConstructor;

Object类型包含了所有的原始/基础类型,原因是对应的属性可以通过原型链访问到 而 object 是不包含原始值的

{}

空对象{}是Object类型的简写形式,所以使用Object时常常用空对象代替。

它描述了一个没有成员的对象。当你试图访问这样一个对象的任意属性时,TypeScript 会产生一个编译时错误。

你仍然可以使用在 Object 类型上定义的所有属性和方法,这些属性和方法可通过 JavaScript 的原型链隐式地使用。

// Type {}
const obj = {};

// "[object Object]"
obj.toString();