Closed far-blue closed 7 years ago
Short answer:
new
(with or without stamps).Long answer:
This article might help: https://medium.com/@koresar/fun-with-stamps-episode-1-stamp-basics-e0627d81efe0
Closer to the end it also explains .prototype
of stamp-made object instances.
If after reading you have questions - please shoot them here.
Cheers :)
Oh, btw. Stamps work with the new
keyword and without it.
var s = require('@stamp/it');
var S = s({props: {a:1}});
console.log( S() ); // { a: 1 }
console.log( new S() ); // { a: 1 }
console.log( Object.getPrototypeOf(S()) === Object.getPrototypeOf(new S()) ); // true
Great to know I can still use 'new' if needed to work with older libraries that don't use Object.create() etc.
Whether we like it or not, a lot of js code expects 'new' to work and so saying "Don't use new" isn't overly helpful.
I certainly wouldn't be surprised if I was missing something here as I'm pretty new to all this but to my understanding 'new' is effectively just creating a new object, setting its prototype and then running the content of the constructor function in the new object's context (i.e. 'this' is the new object). So, really, it is allowing for a form of delegation inheritance through the prototype chain. As such, is it really a bad thing? Certainly when creating thousands of objects with the same methods delegation inheritance is recommended.
I assume using 'new' with a stamp function correctly uses delegation on the prototype chain to prevent copying of methods each time. Or is that assumption wrong?
Sorry not taking enough time to answer your questions.
I'd HIGHLY recommend to read my article - https://medium.com/@koresar/fun-with-stamps-episode-1-stamp-basics-e0627d81efe0 4 minutes read. Half of the questions you asked are answered there.
Here is why stamp's philosophy is to avoid new
keyword - https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3
Stamps do not allow chained (vertical) inheritance. (Chain means more than one connection.)
But stampit does use the .prototype
to share methods between the object instances. It's all in my "Fun with stamps" article.
I call stamp's inheritance model - horizontal.
Your assumption is wrong. The answer is in the same "Fun with stamps" episode.
Feel free to shoot more questions.
If you are good at reading JavaScript than you can understand the internal mechanics of Stamps from this little article: https://medium.com/@koresar/fun-with-stamps-episode-4-implementing-stamps-in-30-loc-e52f5c17dcfe 5 minutes read.
The core is basically 30 lines of code. Should answer almost 100% of your questions. :)
Thank you :)
In your 'fun with stamps' article you mention, in the section 'Objects created by stamps', that the prototype for the objects created by the stamp function is the .methods object from the stamp descriptor which is itself a property of the stamp function. This would suggest my assumption is correct and all objects created by the stamp function use prototype based delegation and the methods are not copied. So it won't be a problem to create thousands of objects from the stamp function.
If I understand the code in ep4 of 'fun with stamps', properties are copied, methods are delegated via the prototype and initializers are run as part of the createFactory() method as described in the section 'Factory function internals'.
Maybe I worded my initial assumption incorrectly. I'm not interested in a hierarchy of chained prototypes. I'm interested in correct use of delegation so that when I create thousands of objects from the same stamp function I'm not creating thousands of copies of all the methods on the objects at the same time. I've seen examples of mixin- and extend-style code that do exactly this and it's a huge memory hog and performance killer :)
I am surprised 'new stampFunction()' works but pleased and although the use of 'new' is discouraged I think people new to stamps and working with mixed codebases would like to know it is possible and what, if any, differences exist between 'stampFunction()' and 'new stampFunction()'.
I was very exciting reading your last comment @far-blue ! :)
Regarding the new
keyword with stamps.
Consider this code:
function CreateRabbit() {
return Object.create({ isRabbit: true });
}
var regularObj = CreateRabbit();
var newObj = new CreateRabbit();
console.log( Object.getPrototypeOf(regularObj) === Object.getPrototypeOf(newObj) ); // true
There is a single difference. While creating rabbit via new
the JS engine would create an empty object and assign it as the function's context. The context is ignored by the function.
Whereas, without new
the function will be called without any context.
This means that creating object from stamps with new
keyword would generate a useless object. Thus putting some unnecessary pressure to the GC.
Closing the issue as resolved. Please open if any.
thank you for all your help :)
Some informative reading on the topic of new
, prototype delegation, etc...
Why new
ing stuff is probably a bad idea... mixed codebase or no:
Class vs Prototypes vs Composition:
The essence of software development is composition. You can't get away from composition even if you try. If you do try to get away from composition, you end up composing anyway -- but you'll do it badly.
Liked your recent article @ericelliott :) Waiting for the continuation!
@koresar Have you read the rest of the series? There are a bunch of installments now...
I'm new to stamps and I'd like to start using them but have existing code that uses constructors to create objects on demand. Is there a recommended way to achieve this?
My initial thinking was to wrap the stamp-generated object creating function in another function that acts as the constructor for use with 'new' but I assume this will break the prototype chain.
I guess what I'd need would be a function that can act as a constructor that sets the resulting object prototype to an object from the stamp but which then also runs the initializers.
Any thoughts?