尝试代理ES6类构造函数时发生TypeError [英] TypeError when trying to Proxy a ES6 class constructor

查看:93
本文介绍了尝试代理ES6类构造函数时发生TypeError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试代理一个ES6构造函数(主要是尝试模仿Python的描述符以进行娱乐和学习):

I'm trying to Proxy a ES6 constructor (mostly trying to emulate Python's descriptors for fun and learning):

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)

如果运行此代码段,则会出现此错误:

If you run this snippet, you'll get this error:

cstr.apply(obj, args)

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

如果我将cstr.apply替换为new cstr,则构造函数会很快耗尽堆栈(显然要进行无限递归).

If I replace cstr.apply with new cstr, the constructor quickly exhausts stack (apparently going into an infinite recursion).

如果我将_Record类替换为一个函数(例如,该可以通过Babel进行编译的),则此可行.我可以使其与本机ES6一起使用吗?

This works if I replace the _Record class with a function (for example, this would work transpiled through Babel). Can I make it work with native ES6?

谢谢.

P. S.如果有问题,我目前正在Node 7.7.4上检查这些摘要.

P. S. I'm currently checking these snippets on Node 7.7.4, if it matters.

推荐答案

零件

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

不适用于ES6类.您需要使用

does not work with ES6 classes. You need to use

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

(而不是您尝试执行的Reflect.construct(cstr, args)new cstr(...args),这实际上是无限递归的-IIRC target引用_Record,而cstr引用Record或其子类之一).

(and not Reflect.construct(cstr, args) or new cstr(...args) that you were trying to do, which indeed recurses infinitely - IIRC target refers to _Record while cstr refers to Record or one of its subclasses).

这篇关于尝试代理ES6类构造函数时发生TypeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆