made with esnextbin
Last active
July 30, 2016 01:42
-
-
Save trxcllnt/0da8f24ad5c54c2e64c217d90b131c5f to your computer and use it in GitHub Desktop.
esnextbin sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>ESNextbin Sketch</title> | |
<!-- put additional styles and scripts here --> | |
</head> | |
<body> | |
<!-- put markup and other contents here --> | |
<div id="app"></div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Specify required named properties for classes that take an object as | |
* their first argument. Curry the class constructor until all required | |
* properties are provided. When all properties are required, return an | |
* instance of the curried class. Maintains prototype constructors so | |
* curried classes can be extended. | |
*/ | |
const MyClass = curryClass(['required', 'props'], class MyClass { | |
constructor(props, ...rest) { | |
console.log(this.constructor.name, JSON.stringify(props), ...rest); | |
this.someMethod(); | |
} | |
someMethod() { | |
console.log(`${this.constructor.name}, 'someMethod' base impl`); | |
} | |
}); | |
const MyClassPartialWithNew = new MyClass({ props: 'props value' }); | |
const MyClassPartial = /**/MyClass({ props: 'props value' }); | |
/* curried ctors ^ can also be called without `new` */ | |
class MyPartialSublass extends MyClassPartial { | |
someMethod() { | |
console.log(`${this.constructor.name}, 'someMethod' subclass partial impl`); | |
} | |
} | |
class MySubclass extends MyClass { | |
someMethod() { | |
console.log(`${this.constructor.name}, 'someMethod' subclass impl`); | |
} | |
} | |
console.clear(); | |
const PartialInstance1 = MyClassPartial({ required: 'property A' }); | |
const PartialInstance2 = new MyClassPartialWithNew({ required: 'property B' }); | |
const PartialSublassInstance = new MyPartialSublass({ required: 'property C'}); | |
const SubclassPartial1 = new MySubclass({ props: 'other value' }, [1, 2, 3]); | |
const SubclassPartial2 = SubclassPartial1({ additional: 'property' }, [4, 5, 6]); | |
const SubclassPartial3 = new SubclassPartial1({ additional: 'property' }, [4, 5, 6]); | |
const SubclassInstance1 = new SubclassPartial2({ required: 'foo' }, [7, 8, 9]); | |
const SubclassInstance2 = new SubclassPartial3({ required: 'bar', more: 'props' }, [10, 11, 12]); | |
console.log(PartialInstance1 instanceof MyClass); | |
console.log(PartialInstance2 instanceof MyClass); | |
console.log(PartialSublassInstance instanceof MyClass); | |
console.log(SubclassInstance1 instanceof MyClass); | |
console.log(SubclassInstance2 instanceof MyClass); | |
console.log(SubclassInstance1 instanceof MySubclass); | |
console.log(SubclassInstance2 instanceof MySubclass); | |
function curryClass(args, ctor, opts = {}, rest = []) { | |
curriedCtor.prototype = Object.create(ctor.prototype); | |
return curriedCtor; | |
function curriedCtor(attr, ...more) { | |
const argsLeft = attr && args.filter((prop) => !attr.hasOwnProperty(prop)); | |
const restArgs = rest.concat(more); | |
const restOpts = {...opts, ...attr}; | |
// If required args remain, curry to the ctor again | |
if (argsLeft && argsLeft.length) { | |
// If `this` is a subclass of the curried ctor, curry to `this.constructor`. | |
// If `this` is an instance of the curried ctor, or if `this` isn't an isntance | |
// of the curried ctor, curry to the captured `curriedCtor` ctor. | |
const nextCtor = this && this instanceof ctor && this.constructor || ctor; | |
if (nextCtor !== ctor) { | |
return curryClass(argsLeft, nextCtor, restOpts, restArgs); | |
} | |
function nextCurriedCtor() { | |
return ctor.apply(this, arguments); | |
} | |
nextCurriedCtor.prototype = Object.create(curriedCtor.prototype); | |
return curryClass(argsLeft, nextCurriedCtor, restOpts, restArgs); | |
} | |
//// | |
// Otherwise, no args left to curry. Invoke or | |
// instantiate the curried ctor with the aggregated | |
// props and args. | |
//// | |
// If `this` is an instance of the curried ctor, the | |
// curried result was called using `new`. Return the | |
// call to the curried ctor. | |
else if (this instanceof ctor) { | |
return ctor.call(this, restOpts, ...restArgs); | |
} | |
//// | |
// If `this` isn't an instance of the curried ctor, | |
// the curried result was called without using `new`. | |
// Instantiate and return an instance of the curried ctor. | |
//// | |
else { | |
return new ctor(restOpts, ...restArgs); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "esnextbin-sketch", | |
"version": "0.0.0", | |
"dependencies": { | |
"babel-runtime": "6.11.6" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); | |
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); | |
var _extends2 = require('babel-runtime/helpers/extends'); | |
var _extends3 = _interopRequireDefault(_extends2); | |
var _create = require('babel-runtime/core-js/object/create'); | |
var _create2 = _interopRequireDefault(_create); | |
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); | |
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); | |
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); | |
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); | |
var _inherits2 = require('babel-runtime/helpers/inherits'); | |
var _inherits3 = _interopRequireDefault(_inherits2); | |
var _stringify = require('babel-runtime/core-js/json/stringify'); | |
var _stringify2 = _interopRequireDefault(_stringify); | |
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | |
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | |
var _createClass2 = require('babel-runtime/helpers/createClass'); | |
var _createClass3 = _interopRequireDefault(_createClass2); | |
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
/* | |
* Specify required named properties for classes that take an object as | |
* their first argument. Curry the class constructor until all required | |
* properties are provided. When all properties are required, return an | |
* instance of the curried class. Maintains prototype constructors so | |
* curried classes can be extended. | |
*/ | |
var MyClass = curryClass(['required', 'props'], function () { | |
function MyClass(props) { | |
var _console; | |
(0, _classCallCheck3.default)(this, MyClass); | |
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | |
rest[_key - 1] = arguments[_key]; | |
} | |
(_console = console).log.apply(_console, [this.constructor.name, (0, _stringify2.default)(props)].concat(rest)); | |
this.someMethod(); | |
} | |
(0, _createClass3.default)(MyClass, [{ | |
key: 'someMethod', | |
value: function someMethod() { | |
console.log(this.constructor.name + ', \'someMethod\' base impl'); | |
} | |
}]); | |
return MyClass; | |
}()); | |
var MyClassPartialWithNew = new MyClass({ props: 'props value' }); | |
var MyClassPartial = /**/MyClass({ props: 'props value' }); | |
/* curried ctors ^ can also be called without `new` */ | |
var MyPartialSublass = function (_MyClassPartial) { | |
(0, _inherits3.default)(MyPartialSublass, _MyClassPartial); | |
function MyPartialSublass() { | |
(0, _classCallCheck3.default)(this, MyPartialSublass); | |
return (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(MyPartialSublass).apply(this, arguments)); | |
} | |
(0, _createClass3.default)(MyPartialSublass, [{ | |
key: 'someMethod', | |
value: function someMethod() { | |
console.log(this.constructor.name + ', \'someMethod\' subclass partial impl'); | |
} | |
}]); | |
return MyPartialSublass; | |
}(MyClassPartial); | |
var MySubclass = function (_MyClass) { | |
(0, _inherits3.default)(MySubclass, _MyClass); | |
function MySubclass() { | |
(0, _classCallCheck3.default)(this, MySubclass); | |
return (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(MySubclass).apply(this, arguments)); | |
} | |
(0, _createClass3.default)(MySubclass, [{ | |
key: 'someMethod', | |
value: function someMethod() { | |
console.log(this.constructor.name + ', \'someMethod\' subclass impl'); | |
} | |
}]); | |
return MySubclass; | |
}(MyClass); | |
console.clear(); | |
var PartialInstance1 = MyClassPartial({ required: 'property A' }); | |
var PartialInstance2 = new MyClassPartialWithNew({ required: 'property B' }); | |
var PartialSublassInstance = new MyPartialSublass({ required: 'property C' }); | |
var SubclassPartial1 = new MySubclass({ props: 'other value' }, [1, 2, 3]); | |
var SubclassPartial2 = SubclassPartial1({ additional: 'property' }, [4, 5, 6]); | |
var SubclassPartial3 = new SubclassPartial1({ additional: 'property' }, [4, 5, 6]); | |
var SubclassInstance1 = new SubclassPartial2({ required: 'foo' }, [7, 8, 9]); | |
var SubclassInstance2 = new SubclassPartial3({ required: 'bar', more: 'props' }, [10, 11, 12]); | |
console.log(PartialInstance1 instanceof MyClass); | |
console.log(PartialInstance2 instanceof MyClass); | |
console.log(PartialSublassInstance instanceof MyClass); | |
console.log(SubclassInstance1 instanceof MyClass); | |
console.log(SubclassInstance2 instanceof MyClass); | |
console.log(SubclassInstance1 instanceof MySubclass); | |
console.log(SubclassInstance2 instanceof MySubclass); | |
function curryClass(args, ctor) { | |
var opts = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; | |
var rest = arguments.length <= 3 || arguments[3] === undefined ? [] : arguments[3]; | |
curriedCtor.prototype = (0, _create2.default)(ctor.prototype); | |
return curriedCtor; | |
function curriedCtor(attr) { | |
for (var _len2 = arguments.length, more = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { | |
more[_key2 - 1] = arguments[_key2]; | |
} | |
var argsLeft = attr && args.filter(function (prop) { | |
return !attr.hasOwnProperty(prop); | |
}); | |
var restArgs = rest.concat(more); | |
var restOpts = (0, _extends3.default)({}, opts, attr); | |
// If required args remain, curry to the ctor again | |
if (argsLeft && argsLeft.length) { | |
var nextCurriedCtor = function nextCurriedCtor() { | |
return ctor.apply(this, arguments); | |
}; | |
// If `this` is a subclass of the curried ctor, curry to `this.constructor`. | |
// If `this` is an instance of the curried ctor, or if `this` isn't an isntance | |
// of the curried ctor, curry to the captured `curriedCtor` ctor. | |
var nextCtor = this && this instanceof ctor && this.constructor || ctor; | |
if (nextCtor !== ctor) { | |
return curryClass(argsLeft, nextCtor, restOpts, restArgs); | |
} | |
nextCurriedCtor.prototype = (0, _create2.default)(curriedCtor.prototype); | |
return curryClass(argsLeft, nextCurriedCtor, restOpts, restArgs); | |
} | |
//// | |
// Otherwise, no args left to curry. Invoke or | |
// instantiate the curried ctor with the aggregated | |
// props and args. | |
//// | |
// If `this` is an instance of the curried ctor, the | |
// curried result was called using `new`. Return the | |
// call to the curried ctor. | |
else if (this instanceof ctor) { | |
return ctor.call.apply(ctor, [this, restOpts].concat((0, _toConsumableArray3.default)(restArgs))); | |
} | |
//// | |
// If `this` isn't an instance of the curried ctor, | |
// the curried result was called without using `new`. | |
// Instantiate and return an instance of the curried ctor. | |
//// | |
else { | |
return new (Function.prototype.bind.apply(ctor, [null].concat([restOpts], (0, _toConsumableArray3.default)(restArgs))))(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment