ES 编码实践 —— 拓展已有方法
published
情境
偏底层的数据库包,很少封装业务逻辑相关的内容,比如创建时间、更新时间。 如果想要在每次更新数据库时,同时更新「更新时间」。要怎么办呢?
常见的解决方法
- 方法 1:调用具体的更新方法时,手动添加更新时间。
- 方法 2:覆写更新方法,使方法被调用时,自动添加更新时间。
为了减少繁冗的代码,当然会选择方法 2。
代码
错误的代码
// db.update 为数据库更新方法
db.update = async function (table, row, options) {
row.updated_at = app.mysql.literals.now
return Reflect.apply(db.update, this, [ table, row, options ])
}
db.update
指向的对象被直接修改。 return Reflect.apply(db.update, this, [ table, row, options ])
中的 db.update
指向修改后的函数,这会造成循环调用。
正确的代码
// db.update 为数据库更新方法
db.update = (function (_super) {
return async function (table, row, options) {
row.updated_at = app.mysql.literals.now
return Reflect.apply(_super, this, [ table, row, options ])
}
})(db.update)
通过闭包将 db.update
所指向的原始函数对象保存在 Reflect.apply(_super, this, [ table, row, options ])
的作用域链中,并通过 _super
调用。
总结
利用闭包拓展已有方法。