```javascript ... const entity = classTransformer.plainToClass( metatype, value, this.transformOptions, ); const errors = await classValidator.validate(entity, this.validatorOptions); ... ``` 如果传入`value = {"aaa":"bbb"}` 那么通过plainToClass()生成的entity的constructor是model里规定的那个class,例如下面 ![](https://i.imgur.com/6ZLsef8.png) ![](https://i.imgur.com/UagPo94.png) 但是如果传入`value = {"aaa":"bbb","__proto__":{}}`,那么plainToClass()生成的entity的constructor将不会是那个class,原因是被传入的__proto__覆盖了。 所以到下一句`classValidator.validate(...)`的时候 有这么三句,我把动态的数值放到注释里 ```javascript /* ValidationExecutor.ts:41 execute(...) */ ... //object = {"aaa":"bbb"...} 这个变量是传入的entity赋值过来的 const groups = this.validatorOptions ? this.validatorOptions.groups : undefined; const targetMetadatas = this.metadataStorage.getTargetValidationMetadatas(object.constructor, targetSchema, groups); const groupedMetadatas = this.metadataStorage.groupByPropertyName(targetMetadatas); ... ``` 然后在第二句`this.metadataStorage.getTargetValidationMetadatas(object.constructor, ...)` ```javascript /* MetadataStorage.ts:65 */ getTargetValidationMetadatas(targetConstructor: Function, targetSchema: string, groups?: string[]): ValidationMetadata[] { // get directly related to a target metadatas const originalMetadatas = this.validationMetadatas.filter(metadata => { if (metadata.target !== targetConstructor && metadata.target !== targetSchema) return false; if (metadata.always) return true; if (groups && groups.length > 0) return metadata.groups && !!metadata.groups.find(group => groups.indexOf(group) !== -1); return true; }); ... ``` metadata.target就是model定义的class 可以发现它对object.constructor(targetConstructor)和metadata.target进行了比对,如果不相等,直接就返回false了,从而导致整体最后是一个空结果(targetMetadatas),然后到`groupedMetadatas`这里结果也是空。 如果我们不进行破坏,预期这里是true,而且最后通过一系列的操作会取出定义的filter到`groupedMetadatas`,然后会遍历`groupedMetadatas`对用户输入进行检测。 但是进行破坏的话,`groupedMetadatas`就是空的,所以根本不会走filter了...(他用的是一个foreach遍历的)