Skip to content

Commit 4151ab3

Browse files
committed
util: add createClassWrapper to internal/util
Utility function for wrapping an ES6 class with a constructor function that does not require the new keyword PR-URL: #11391 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
1 parent 804bb22 commit 4151ab3

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

lib/internal/util.js

+20
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,23 @@ exports.toLength = function toLength(argument) {
186186
const len = toInteger(argument);
187187
return len <= 0 ? 0 : Math.min(len, Number.MAX_SAFE_INTEGER);
188188
};
189+
190+
// Useful for Wrapping an ES6 Class with a constructor Function that
191+
// does not require the new keyword. For instance:
192+
// class A { constructor(x) {this.x = x;}}
193+
// const B = createClassWrapper(A);
194+
// B() instanceof A // true
195+
// B() instanceof B // true
196+
exports.createClassWrapper = function createClassWrapper(type) {
197+
const fn = function(...args) {
198+
return Reflect.construct(type, args, new.target || type);
199+
};
200+
// Mask the wrapper function name and length values
201+
Object.defineProperties(fn, {
202+
name: {value: type.name},
203+
length: {value: type.length}
204+
});
205+
Object.setPrototypeOf(fn, type);
206+
fn.prototype = type.prototype;
207+
return fn;
208+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
require('../common');
5+
const assert = require('assert');
6+
const util = require('internal/util');
7+
8+
const createClassWrapper = util.createClassWrapper;
9+
10+
class A {
11+
constructor(a, b, c) {
12+
this.a = a;
13+
this.b = b;
14+
this.c = c;
15+
}
16+
}
17+
18+
const B = createClassWrapper(A);
19+
20+
assert.strictEqual(typeof B, 'function');
21+
assert(B(1, 2, 3) instanceof B);
22+
assert(B(1, 2, 3) instanceof A);
23+
assert(new B(1, 2, 3) instanceof B);
24+
assert(new B(1, 2, 3) instanceof A);
25+
assert.strictEqual(B.name, A.name);
26+
assert.strictEqual(B.length, A.length);
27+
28+
const b = new B(1, 2, 3);
29+
assert.strictEqual(b.a, 1);
30+
assert.strictEqual(b.b, 2);
31+
assert.strictEqual(b.c, 3);

0 commit comments

Comments
 (0)