Haven't yet had chance to read the similarly named one on TypeScript.
There isn't one.
But when Microsoft states "so that the programmers at Microsoft could bring traditional object-oriented programs to the web" they are talking about C# style class-based object-orientation.
TypeScript was designed with a good class-based OO development experience in mind - sacrificing the ease of other approaches that may be equally valid under JavaScript (which claims to be multi-paradigm).
I also believe even before introduction of 'class' it was never mainstream approach.
You are correct. Because mainstream OO is "class-based". "OOP with closures" is only about objects, not classes.
The approach that was always considered "correct" was prototypal OO.
I would argue that the mainstream didn't even accept "prototypal OO" as correct given that there is no explicit class mechanism and the confusion that it caused up to and including ES5. But it certainly is possible to emulate class-based OO with prototypal OO. Strictly speaking membership to a class should last for the lifetime of the object. JavaScript objects can be augmented after construction - so "class membership" isn't fixed.
Class was a straight forward thing that is widely understood and played perfectly well with JS prototype thing.
The important aspect was that it aligned with the mainstream mindset of class-based object-orientation. However the code before ES2015 wasn't straightforward.
some benefits
You missed:
Elimination of inheritance. Commonalities have to be managed entirely through composition.
Don't need new to instantiate an object (useful if instances are cached);
ES7 supports private members through #privateMember
They landed in Chrome 74 but as such the proposal has been stuck at stage 3 since 2017 - it didn't get into ES2020; maybe it will be part of ES2021 (ES2016 is ECMA-262 7ᵗʰ Edition).
Regarding the this bounding problem
The problem with this has more to do with developers from other languages not understanding how it works - that it is a deliberate decision not to bind the function to the object.
(something like x' in ReScript)
'x is a simply type variable just like T is a type variable in Op2Args<T>. And the object returned by the factory still has a structural type.
keyword instanceof just no longer makes any sense,
instanceof can be a great escape hatch but the whole point of polymorphism is that the object should know what to do without the type needing to be known first (Replace Conditional with Polymorphism).
I completely miss the point of trying to use functions for OO where classes are available to implement OO.
There isn't just one kind of object-orientation. You are correct that the mainstream assumes "class-based object-orientation" when OO is mentioned; really COP - class-oriented programming would have been a better name (the code is declaring classes, not assembling objects).
"OOP with closures" doesn't seek to emulate "class-based object-orientation". Without inheritance, composition is the only option which leads to a simpler style of object-orientation. Also the notion isn't that "closures are like classes" but that "closures are like objects".
Once "closures are like objects" sinks in, it should become apparent that there are situations where closures can be more succinct than objects (created by a class).
Also consider that in 2008 ES5 wasn't even finalized yet - class wasn't official until 2015.
Which one is easier to understand
// closures as objectsfunctionphone(phoneNumber){return{getPhoneNumber:getPhoneNumber,getDescription:getDescription};functiongetPhoneNumber(){returnphoneNumber;}functiongetDescription(){return'This is a phone that can make calls.';}}functionsmartPhone(phoneNumber,signature){varcore=phone(phoneNumber);signature=signature||'sent from '+core.getPhoneNumber();return{getPhoneNumber:core.getPhoneNumber,getDescription:getDescription,sendEmail:sendEmail};functiongetDescription(){returncore.getDescription()+' It can also send email messages';}functionsendEmail(emailAddress,message){console.log('To: '+emailAddress+'\n'+message+'\n'+signature);}}
Or this one?
// Combination inheritance// prototype chaining + constructor stealing//functionPhone(phoneNumber){this.phoneNumber=phoneNumber;}functiongetPhoneNumber(){returnthis.phoneNumber;}functiongetDescription(){return'This is a phone that can make calls.';}Phone.prototype.getPhoneNumber=getPhoneNumber;Phone.prototype.getDescription=getDescription;functionSmartPhone(phoneNumber,signature){Phone.call(this,phoneNumber);// inherit propertiesthis.signature=signature||'sent from '+this.getPhoneNumber();}SmartPhone.prototype=newPhone();// inherit methodsfunctionsendEmail(emailAddress,message){console.log('To: '+emailAddress+'\n'+message+'\n'+this.signature);}functiongetDescriptionSmart(){vardescription=Phone.prototype.getDescription.call(this);returndescription+' It can also send email messages';}SmartPhone.prototype.sendEmail=sendEmail;SmartPhone.prototype.getDescription=getDescriptionSmart;
If you had to write a bigger piece of code in js then Closure Compiler was the tool to go with, it would be either impossible, or you'd need to invent your own tools.
Not everybody has Google size problems - and the tradeoffs of the closure-based approach are known.
Clearly in a project using the Closure compiler one would stick to the recommended coding practices. But when in the past I had a look at the Closure library it struck me that it was organized to appeal to Java programmers - so it's not that surprising that the compiler would favour the pseudo-classical approach (apart from being more optimizable).
In any case I'm not recommending ignoring class - just to be familiar with the closure based approach; it does exist in the wild and in some situations it could come in handy.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
There isn't one.
But when Microsoft states "so that the programmers at Microsoft could bring traditional object-oriented programs to the web" they are talking about C# style class-based object-orientation.
TypeScript was designed with a good class-based OO development experience in mind - sacrificing the ease of other approaches that may be equally valid under JavaScript (which claims to be multi-paradigm).
You are correct. Because mainstream OO is "class-based". "OOP with closures" is only about objects, not classes.
I would argue that the mainstream didn't even accept "prototypal OO" as correct given that there is no explicit class mechanism and the confusion that it caused up to and including ES5. But it certainly is possible to emulate class-based OO with prototypal OO. Strictly speaking membership to a class should last for the lifetime of the object. JavaScript objects can be augmented after construction - so "class membership" isn't fixed.
The important aspect was that it aligned with the mainstream mindset of class-based object-orientation. However the code before ES2015 wasn't straightforward.
You missed:
new
to instantiate an object (useful if instances are cached);They landed in Chrome 74 but as such the proposal has been stuck at stage 3 since 2017 - it didn't get into ES2020; maybe it will be part of ES2021 (ES2016 is ECMA-262 7ᵗʰ Edition).
The problem with
this
has more to do with developers from other languages not understanding how it works - that it is a deliberate decision not to bind the function to the object.'x
is a simply type variable just likeT
is a type variable inOp2Args<T>
. And the object returned by the factory still has a structural type.instanceof
can be a great escape hatch but the whole point of polymorphism is that the object should know what to do without the type needing to be known first (Replace Conditional with Polymorphism).There isn't just one kind of object-orientation. You are correct that the mainstream assumes "class-based object-orientation" when OO is mentioned; really COP - class-oriented programming would have been a better name (the code is declaring classes, not assembling objects).
"OOP with closures" doesn't seek to emulate "class-based object-orientation". Without inheritance, composition is the only option which leads to a simpler style of object-orientation. Also the notion isn't that "closures are like classes" but that "closures are like objects".
Once "closures are like objects" sinks in, it should become apparent that there are situations where closures can be more succinct than objects (created by a class).
Also consider that in 2008 ES5 wasn't even finalized yet -
class
wasn't official until 2015.Which one is easier to understand
Or this one?
Not everybody has Google size problems - and the tradeoffs of the closure-based approach are known.
Clearly in a project using the Closure compiler one would stick to the recommended coding practices. But when in the past I had a look at the Closure library it struck me that it was organized to appeal to Java programmers - so it's not that surprising that the compiler would favour the pseudo-classical approach (apart from being more optimizable).
In any case I'm not recommending ignoring
class
- just to be familiar with the closure based approach; it does exist in the wild and in some situations it could come in handy.