0

我正在尝试代理 ES6 构造函数(主要是尝试模拟 Python 的描述符以获得乐趣和学习):

class _Record {
    constructor(data) {
        this._data = data;
    }
}

const constrProxyHandlers = {
    construct: function(target, args, cstr) {
        let instProxyHandler = {
            get: (target, prop) => {
                if(prop in target._data) { return target._data[prop] }
                return target[prop]
            },
            set: (target, prop, val) => {
                if(prop in target._data) {
                    target._data[prop] = val;
                } else {
                    target[prop] = val;
                }
                return true
            }
        }
        
        let obj = Object.create(cstr.prototype)
        cstr.apply(obj, args)
        return new Proxy(obj, instProxyHandler)
    }
}

const Record = new Proxy(_Record, constrProxyHandlers)

let rec = new Record({name: 'Vic', age: 25})
console.log([rec.name, rec.age])
rec.name = 'Viktor'
console.log(rec)

如果您运行此代码段,您将收到此错误:

cstr.apply(obj, args)

TypeError: Class constructor _Record cannot be invoked without 'new'

如果我替换cstr.applynew cstr,构造函数会很快耗尽堆栈(显然进入无限递归)。

如果我用函数替换类(例如,这通过 Babel 转译) ,这将起作用。我可以让它与原生 ES6 一起工作吗?_Record

谢谢你。

PS 我目前正在节点 7.7.4 上检查这些片段,如果它重要的话。

4

1 回答 1

2

那个部分

let obj = Object.create(cstr.prototype)
cstr.apply(obj, args)

不适用于 ES6 类。你需要使用

let obj = Reflect.construct(target, args, cstr);

(而不是Reflect.construct(cstr, args)或者new cstr(...args)你试图做的,这确实是无限递归的——IIRCtarget指的是_Recordwhilecstr指的是Record或其子类之一)。

于 2017-03-29T21:30:11.243 回答