Class vs 在 JavaScript 中定义 IndexedDB 存储的函数

Class vs Function to Define an IndexedDB Store in JavaScript

正如您从我的问题中看到的那样,我是 TypeScript/JavaScript 的新手。我正在开发一个使用 IndexedDB 的 Blazor Wasm 应用程序。我注意到有这 2 种(毫无疑问还有更多)方法可以为数据库的存储创建对象。我想知道什么(如果有的话)有利于一种方法而不是另一种方法。显然,函数方法要简洁得多。但是 class 方法在概念上似乎更好。

class myObject
{
    _property1: string;
    _property2: number;

    constructor(parm1, parm2)
    {
        this.property1 = parm1;
        this.property2 = parm2;
    }

    get property1() { return this._property1; }
    set property1(value1) { this._property1 = value1; }

    get property2() { return this._property2; }
    set property2(value2) { this._property2 = value2; }
}

function myObject(parm1, parm2)
{
    return { property1: parm1, property2: parm2 };
}

类 是可序列化的,但在这样做时函数被删除了。要在读取后重新创建 class,您需要将每个读取操作加倍。 indexedDB 将以非 class 形式加载数据,然后您需要创建 class,然后使用类似 Object.assign 的方法将数据复制到 class 成员中。如果你在任何地方都使用 function.call 风格的语法,你可以不用副本就可以逃脱,但如果方法访问 this.

即使这样也会有问题

真是一团糟。只是不要这样做。只需使用普通对象,例如"data".

其他语言具有将序列化数据强制转换回 class 的高效工具,如反序列化。 Javascript 没有。通过在 javascript 中执行此 class read/write 内容,您所做的一切都会使您的程序不必要地变慢。

零成本输入断言示例

function loadObject(db: IDBDatabase, id: number) {
  return new Promise((resolve, reject) => {
   const txn = db.transaction('store');
   const store = txn.objectStore('store');
   const request = store.get(id);
   request.onsuccess = event => resolve(event.target.result);
   request.onerror = event => reject(event.target.error);
  });
}

interface MyObject {
  id: number;
  _property1: string;
  _property2: number;
}

function isMyObject(value: any): value is MyObject {
  return typeof values === 'object' && value !== null && 
    Number.isInteger(value.id) and typeof value._property1 === 'string'
      && 'etc...';
}

async function loadObjectWithTypeAssertion(db, id) {
  // Load object as type 'any'
  const object = await loadObject(db, id);

  // Prove to the typescript compiler that the 'any' type 
  // is in fact an instance of the 'MyObject' type
  if (!isMyObject(object)) {
    throw new Error('object loaded from db is not type MyObject');
  }

  // At this point because we are after the type assertion call,
  // object is now type "MyObject" in intellisense
  // Thefore the return type of this async function is now 
  // Promise<MyObject>

  return object;
}

Object.assign 例子

前面示例中的假装函数仍然存在。


class MyObject() {
  private _property1: string;
  private _property2: number;
}

async function loadAndAssign(...) {
  const object = loadObject(...);

  // Create an empty instance of MyObject
  const myObject = new MyObject();

  // Copy the data loaded from db into the instance
  Object.assign(myObject, object);  

  // Now the "myObject" instance has props

  return myObject;
}