Permalink
Browse files

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>
  • Loading branch information...
jasnell committed Feb 15, 2017
1 parent 804bb22 commit 4151ab398b8186f10056c4551edfa0204e529035
Showing with 51 additions and 0 deletions.
  1. +20 −0 lib/internal/util.js
  2. +31 −0 test/parallel/test-internal-util-classwrapper.js
View
@@ -186,3 +186,23 @@ exports.toLength = function toLength(argument) {
const len = toInteger(argument);
return len <= 0 ? 0 : Math.min(len, Number.MAX_SAFE_INTEGER);
};
// Useful for Wrapping an ES6 Class with a constructor Function that
// does not require the new keyword. For instance:
// class A { constructor(x) {this.x = x;}}
// const B = createClassWrapper(A);
// B() instanceof A // true
// B() instanceof B // true
exports.createClassWrapper = function createClassWrapper(type) {
const fn = function(...args) {
return Reflect.construct(type, args, new.target || type);
};
// Mask the wrapper function name and length values
Object.defineProperties(fn, {
name: {value: type.name},
length: {value: type.length}
});
Object.setPrototypeOf(fn, type);
fn.prototype = type.prototype;
return fn;
};
@@ -0,0 +1,31 @@
// Flags: --expose-internals
'use strict';
require('../common');
const assert = require('assert');
const util = require('internal/util');
const createClassWrapper = util.createClassWrapper;
class A {
constructor(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
}
}
const B = createClassWrapper(A);
assert.strictEqual(typeof B, 'function');
assert(B(1, 2, 3) instanceof B);
assert(B(1, 2, 3) instanceof A);
assert(new B(1, 2, 3) instanceof B);
assert(new B(1, 2, 3) instanceof A);
assert.strictEqual(B.name, A.name);
assert.strictEqual(B.length, A.length);
const b = new B(1, 2, 3);
assert.strictEqual(b.a, 1);
assert.strictEqual(b.b, 2);
assert.strictEqual(b.c, 3);

0 comments on commit 4151ab3

Please sign in to comment.