3.8.6 Object.defineProperty 不生效

Creator 版本:3.8.6
目标平台:Google
重现方式:必现
首个报错:无
问题描述:Object.defineProperty修改get/set方法不生效,打断点发现并没执行,代码在2.4平台是有效的

框架代码

import UUID from "./UUID";

export default class SingletonFactory {
    private static _instances = new Map<string, any>();
    public static getInst<T>(classType: { new(...args): T }): T {
        let key = classType['_singletonId'];
    
        if (!key || !this._instances[key]){
            console.error("无实例");
            return null;
        }

        return this._instances[key];
    }

    static setInst(classType, ...args): void {
        if(classType._singletonId)
            return;
        let key = UUID.generateUUID();
        while (this._instances[key]) {
            key = UUID.generateUUID();
        }
        this._instances[key] = new classType(...args);
        classType._singletonId = key;
    }
}

export function Singleton(...args) {
    return function (target: any) {
        if (checkIsClass(target)){
            SingletonFactory.setInst(target, ...args);
        }
    }
}

export function Autowired<T>(constructor: new (...args) => T) {
    return function (target: any, propertyName) {
        Object.defineProperty(target, propertyName, {
            configurable: true,
        get: function () {
            return SingletonFactory.getInst(constructor);
        },
        set: function(value) {}
    })
}
}

const checkIsClass = function (target: unknown): boolean {
    return (
        typeof target === "function" && 
        "prototype" in target && 
        target.prototype.constructor === target
    );
}

测试代码

import { _decorator } from 'cc';
import { FullView, onShow } from './Tea/UI/UIView';
import { Panel2 } from './Panel2';
import SingletonFactory, { Autowired } from './Tea/Util/SingletonFactory';
import EventManager from './Tea/Util/EventManager';
const { ccclass, property } = _decorator;

@ccclass('Panel1')
export class Panel1 extends FullView {
    @Autowired(EventManager)
    eventManager: EventManager = null;

    @onShow
    init(){
        console.log("EventManager:", SingletonFactory.getInst(EventManager));
        console.log("EventManager:", this.eventManager);
    }

    onClick(){
        Panel2.show();
    }
}

打印结果

Object.defineProperty是不支持了吗,如果希望继续使用装饰器的方式写有什么方案

已解决

export function Autowired<T>(constructor: new (...args) => T) {
    return function (target: any, propertyName) {
        delete target[propertyName];
        const handler: PropertyDescriptor = {
            get: function () {
                return SingletonFactory.getInst(constructor);
            },
            set: function(value) {},
            enumerable: true,
            configurable: true,
        }

        return handler;
    }
}
``` javascript

不要和装饰器混用

在我这边项目不跟装饰器混用,用它的意义就不大了 :joy:

这个东西的历史问题很大,ts标准中 装饰器包括stage2,stage3提案,babel编译包括define语义、set语义,各种编译配置排列组合后会出现奇怪的情况, 能不碰就不要碰,哪天升级了可能就不正常了

明白了,谢谢回答

试试Proxy,按理说Proxy不存在这个问题,而且功能更强大