在 ES-6 class 中扩展 express-js:无法绑定 getter 和 setter
Extending express-js in a ES-6 class: trouble binding getter and setter
我很感兴趣在扩展 class 中使用 Express。我想为 属性 定义 getter 和 setter,但这样做不会将方法绑定到实例。一种解决方法是创建自定义 getter 和 setter 方法并将其绑定到构造函数上,但感觉不对。
const express = require("express");
export default class Application extends express {
_endpoints;
constructor() {
super();
this._endpoints = null;
}
get endpoints() {
return this._endpoints;
}
set endpoints(paths: []) {
this._endpoints = new Set(...paths);
}
}
const myApp = new Application();
console.log(myApp) // ...express-app-object, _endpoints, and nothing related to the getter and setter defined.
console.log(myApp._endpoints) // null
console.log(myApp.endpoints) // undefined
这显然与 express
不是 class 或构造函数这一事实有关,它是一个工厂函数。当你调用 super()
时,它会调用 express()
并创建一个全新的对象,它不是你的对象,也没有你的原型。引用 myApp._endpoints
之所以有效,是因为您的构造函数将构造函数中的 属性 分配给了 express()
创建的对象,但该对象没有附加您的原型,它是 Express 创建的新对象.
如果您从代码中删除 extends express
并注释掉 super()
,您会发现一切正常。
如果您将 express 更改为 Javascript 中任何其他实际定义的 class
,您的 endpoints()
getter 工作正常。
因此,您不能以这种方式扩展 express。
express 原型可用,您可以按照使用 class
关键字之前的方式向其添加内容。
我根本不建议在这里使用 class
,因为这意味着任何阅读您的代码的人都可以为 class 定义方法并期望它们起作用(但它们不起作用) .
相反,只需定义您自己的调用快速工厂函数的工厂函数,然后向它的对象添加属性 returns:
// factory function for my app
function Application() {
const app = express();
// add instance properties
app._endpoints = null;
// add getters/setters
Object.defineProperty(app, "endpoints", {
get: function () {
return this._endpoints;
},
set: function (paths: any[]) {
this._endpoints = new Set([...paths]);
},
enumerable: true,
configurable: true,
});
return app;
}
这可以用作:
app = Application();
或:
app = new Application();
export class Application extends express {
private _endpoints = null;
constructor() {
super();
Object.defineProperty(this, "endpoints", {
get: function () {
return this._endpoints;
},
set: function (paths: any[]) {
this._endpoints = new Set([...paths]);
},
enumerable: true,
configurable: true,
});
}
}
正常使用:
const app = new Application();
console.log(app.endpoints) // null
app.endpoints = ['/auth/signin', '/auth/signout']
console.log(app.endpoints) // Set(2) { '/auth/signin', '/auth/signout' }
我很感兴趣在扩展 class 中使用 Express。我想为 属性 定义 getter 和 setter,但这样做不会将方法绑定到实例。一种解决方法是创建自定义 getter 和 setter 方法并将其绑定到构造函数上,但感觉不对。
const express = require("express");
export default class Application extends express {
_endpoints;
constructor() {
super();
this._endpoints = null;
}
get endpoints() {
return this._endpoints;
}
set endpoints(paths: []) {
this._endpoints = new Set(...paths);
}
}
const myApp = new Application();
console.log(myApp) // ...express-app-object, _endpoints, and nothing related to the getter and setter defined.
console.log(myApp._endpoints) // null
console.log(myApp.endpoints) // undefined
这显然与 express
不是 class 或构造函数这一事实有关,它是一个工厂函数。当你调用 super()
时,它会调用 express()
并创建一个全新的对象,它不是你的对象,也没有你的原型。引用 myApp._endpoints
之所以有效,是因为您的构造函数将构造函数中的 属性 分配给了 express()
创建的对象,但该对象没有附加您的原型,它是 Express 创建的新对象.
如果您从代码中删除 extends express
并注释掉 super()
,您会发现一切正常。
如果您将 express 更改为 Javascript 中任何其他实际定义的 class
,您的 endpoints()
getter 工作正常。
因此,您不能以这种方式扩展 express。
express 原型可用,您可以按照使用 class
关键字之前的方式向其添加内容。
我根本不建议在这里使用 class
,因为这意味着任何阅读您的代码的人都可以为 class 定义方法并期望它们起作用(但它们不起作用) .
相反,只需定义您自己的调用快速工厂函数的工厂函数,然后向它的对象添加属性 returns:
// factory function for my app
function Application() {
const app = express();
// add instance properties
app._endpoints = null;
// add getters/setters
Object.defineProperty(app, "endpoints", {
get: function () {
return this._endpoints;
},
set: function (paths: any[]) {
this._endpoints = new Set([...paths]);
},
enumerable: true,
configurable: true,
});
return app;
}
这可以用作:
app = Application();
或:
app = new Application();
export class Application extends express {
private _endpoints = null;
constructor() {
super();
Object.defineProperty(this, "endpoints", {
get: function () {
return this._endpoints;
},
set: function (paths: any[]) {
this._endpoints = new Set([...paths]);
},
enumerable: true,
configurable: true,
});
}
}
正常使用:
const app = new Application();
console.log(app.endpoints) // null
app.endpoints = ['/auth/signin', '/auth/signout']
console.log(app.endpoints) // Set(2) { '/auth/signin', '/auth/signout' }