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;
}
正如您从我的问题中看到的那样,我是 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;
}