JavaScript/TypeScript类中@符号有什么作用?AdonisJS的@column如何工作?
问题背景
你给出的AdonisJS模型代码示例如下:
import { column, BaseModel } from '@ioc:Adonis/Lucid/Orm' export default class Post extends BaseModel { @column({ isPrimary: true }) public id: number @column() public title: string @column() public description: string }
你猜测@column是创建多个column类的实例作为成员变量,同时疑问手写构造函数赋值的写法是否等价:
export default class Post extends BaseModel { constructor() { this.id = new column({ isPrimary: true }); this.title = new column(); this.description = new column(); } }
解答
1. @符号与@column装饰器的作用&运行原理
@是TypeScript/ECMAScript的装饰器语法,本质是一个特殊的高阶函数,会在代码编译阶段自动执行,用来给类、类属性、类方法等添加额外的元数据或者修改其行为。
AdonisJS Lucid ORM提供的@column是属性装饰器,作用是为ORM注册类属性和对应数据库表字段的映射关系,并不是直接创建column实例作为类属性。它会把你传入的配置(比如是否是主键isPrimary、自定义字段名、数据序列化规则等)和属性名一起,写入类的元数据存储中。
BaseModel底层执行CRUD操作时,会读取这些元数据完成对应逻辑:
- 查询时自动把数据库返回的字段值赋值给对应类属性,做自动数据类型转换
- 写入时自动把类属性映射到对应表字段生成SQL语句
- 主键、自动生成时间戳等特殊字段的逻辑也会依赖这些元数据判断
2. 两种写法是否等价?
完全不等价。
你手写的构造函数写法是直接把id/title等实例属性赋值为column类的实例,实际使用时你给这些属性赋值业务数据(比如post.title = '新文章标题')会直接覆盖掉column实例,ORM也读不到字段的映射配置,完全无法正常工作。
而@column装饰器的写法不会修改属性本身的存值逻辑,属性还是用来存储业务数据,映射配置单独存在类的元数据里,不会和业务值冲突。
内容的提问来源于stack exchange,提问作者Ryan Griggs
相关产品推荐
相关产品推荐

