Here are some experiments creating new objects in JavaScript... with regular functions and generator functions.
Why?
I've been playing around converting regular functions into generator functions, and I recently ran into a problem: generators are not "new-able". You can't create new objects when the constructor is a generator.
Some background: "Generator expressions cannot be used as constructors." http://stackoverflow.com/questions/32039390/why-are-generator-methods-constructors https://github.com/tc39/tc39-notes/blob/master/es7/2015-07/july-29.md#revisit-67-new--generatorfunction tc39/ecma262#171 https://github.com/anba/test262/commit/bd8c91e250690567240e3aa4ade9a740b94b1aee
So I needed a workaround: How do I create a new object and call the constructor when the constructor (and all its methods) are generators?
Well, with JavaScript, where there's a will, there's a way to implement Atwood's Law any way you want to.
During my research, I found these answers on Stack Overflow was incredibly helpful: http://stackoverflow.com/a/21763808 http://stackoverflow.com/a/29037611
(Tested with Node v6.9.1)
function* Person(name) {
this.name = name;
}
Person.prototype.getName = function* () {
console.log(this.name);
}
var p = new Person("Emmet");
Usage:
------
> var p = new Person("Emmet");
TypeError: Person is not a constructor
Now, let's start experimenting with solutions, starting with a simple standard object
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
console.log(this.name);
}
var p = new Person("Emmet");
Usage:
------
> p.getName()
Emmet
> p
Person { name: 'Emmet' }
>
function Person(name) {
this.name = name;
}
my_person_prototype = {
getName: function() {
console.log(this.name);
}
};
var p = {};
for(var key in my_person_prototype) {
p[key] = my_person_prototype[key];
}
Person.apply(p, ["Emmet"]);
Usage:
------
> p.getName()
Emmet
> p
{ getName: [Function: getName], name: 'Emmet' }
>
function Person(name) {
this.name = name;
}
my_person_prototype = {
getName: function() {
console.log(this.name);
}
};
var p = Object.create(my_person_prototype);
Person.apply(p, ["Emmet"]);
Usage:
------
> p.getName()
Emmet
> p
{ name: 'Emmet' }
>
now with generator methods...
function Person(name) {
this.name = name;
}
my_person_prototype = {
getName: function* () {
console.log(this.name);
}
};
var p = {};
for(var key in my_person_prototype){
p[key] = my_person_prototype[key];
}
Person.apply(p, ["Emmet"]);
Usage:
------
> p.getName().next()
Emmet
{ value: undefined, done: true }
> p
{ getName: [Function: getName], name: 'Emmet' }
>
now with generator methods...
function Person(name){
this.name = name;
}
my_person_prototype = {
getName: function* () {
console.log(this.name);
}
};
var p = Object.create(my_person_prototype);
Person.apply(p, ["Emmet"]);
Usage:
------
> p.getName().next()
Emmet
{ value: undefined, done: true }
> p
{ name: 'Emmet' }
>
with a generator constructor and generator methods...
function* Person(name){
this.name = name;
}
my_person_prototype = {
getName: function* () {
console.log(this.name);
}
};
var p = Object.create(my_person_prototype);
Person.apply(p, ["Emmet"]).next()
Usage:
------
> p.getName().next()
Emmet
{ value: undefined, done: true }
> p
{ name: 'Emmet' }
>
with a generator constructor and generator methods... (cleaned up a little bit)
function* Person(name){
this.name = name;
}
Person.prototype.getName = function* () {
console.log(this.name);
}
var p = Object.create(Person.prototype);
Person.apply(p, ["Emmet"]).next()
Usage:
------
> p.getName().next()
Emmet
{ value: undefined, done: true }
> p
{ name: 'Emmet' }
>
// Victory! \o/