Skip to content

(proxied function).prototype = ... #11

fuson opened this Issue Dec 9, 2012 · 2 comments

2 participants

fuson commented Dec 9, 2012

Environment: Node.js


const f = function () {

const pf = Proxy(f, ...);

pf.prototype = {}; // This statement will cast exception

@tvcutsem tvcutsem was assigned Dec 18, 2012

Thanks for reporting. I know what causes the error, but am not yet sure how to fix it. I will send e-mail to es-discuss to discuss the best fix to the problem.

In a nutshell, what happens is the following:

fp.prototype = {} // this triggers the proxy's "set" trap
// since the "set" trap is not defined, the proxy defaults to calling:
Reflect.set(f, 'prototype', {}, fp) // note: the proxy fp itself is being passed as the "receiver" argument to Reflect.set

Inside Reflect.set, a test is made to check whether f === fp.
If this test is true, Reflect.set tries to update the existing 'prototype' property to the "receiver"
If this test is false, Reflect.set tries to add a new data property to the "receiver"

Since f === fp will fail, Reflect.set tries to add the data property {value: {}, enumerable:true, writable: true, configurable:true } to fp. The proxy in turn forwards this operation and tries to add the property to f, which fails because f already defines a property with the same name which is non-configurable, and one cannot change a non-configurable property into a configurable property.

There are a couple of fixes:
1) let the default "set" trap forward the operation as
Reflect.set(f, 'prototype', {}, f) rather than Reflect.set(f, 'prototype', {}, fp)

2) change the f === fp test in Reflect.set to take proxies into account explicitly, and change it to:
(f === fp || fp is a proxy for f)

@tvcutsem tvcutsem added a commit that referenced this issue Dec 20, 2012
@tvcutsem fixed issue #11 b4b2f7a

The issue has been fixed. See commit notes referenced above.

@tvcutsem tvcutsem closed this Dec 20, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.