Herby Vojčík wrote:
Hello,
I now realized that I had a mistake in my mental model and that the
difference is smaller than I thought. Whatever LHS is, it always behaves
the same: it is set as a {[Prototype]] of the RHS. Putting RHS.prototype
into LHS.prototype is pure "addon". Seeing it this way, it is ok.
Even when it is only "addon", it is in fact different behaviour.
It would be nice if
x <| whatever-blueprint
could be defined so that object is created from whatever-blueprint and
its [[Prototype]] is set to x. Even if RHS is function expression (or
whatever in the future).
I'd suggest that setting parallel constructor/prototype hierarchy (very
nice thing which should definitely be in the language), should be
provided by different means. namely by class-specific keyword extends.
const Fox = function (...) extends Animal { ... } // expression
function Fox (...) extends Animal { ... } // declaration
This could kill two bird in one stone: <| could have consistent
prototypal semantics all over, and doing class-like double hierarchy
would be done with well-known class-domain keyword.
What do you think?
Herby
Allen Wirfs-Brock wrote:
On Mar 4, 2012, at 1:59 PM, Herby Vojčík wrote:
Hello,
I feel uneasy about this in <| proposal:
If the LHS operand has a property named prototype and the RHS
operand is a function expression then the [[Prototype]] of the
function object is set to the LHS object and the prototype property
of the new function is set to a new object whose [[Prototype]] is the
value of the LHS’s prototype property.
It looks a little "perlish" to me, in the sense that when you write
x <| function (...) {...}
you must guard what x is because you can get two different outcomes
(same as perl can use element in place of container, which backfires if
the element itself is a container). I think it should be rephrased as:
If the RHS operand is a function expression then
a. if the LHS operand has a property named prototype the
[[Prototype]] of the function object is set to the LHS object and the
prototype property of the new function is set to a new object whose
[[Prototype]] is the value of the LHS’s prototype property.
b. otherwise TypeError exception is thrown.
Herby
Here[1] is a specific instance of how this feature is useful:
//define a non constructible superclass that provides some
Smalltalk-like conventions
const AbstractClass = Function.prototype <| {
subclassResponsibility() {throw new Error(this.name+" did not
implemented an abstract method")},
shouldNotImplement() {throw new Error(this.name+" should not implemented
by "+this.name)},
name: "AbstractClass",
prototype: Object.prototype <|{
get class() {return this.constructor},
error(message) {throw new Error(message)},
subclassResponsibility() {return this.class.subclassResponsibility()},
shouldNotImplement() {return this.class.shouldNotImplement()},
errorSubscriptBounds(index) {this.error("subscript is out of bounds:
"+index)}
}
};
See the full js file for its use in context. But the basic idea is that
we need to set up the root of both the class-side and instance-side
inheritance chains. Your definition would make that impossible. This is
an unusual use-case but it does occur when working at the root
inheritance level. In addition to this specific example I think it will
be useful when languages that are compile to JS need to implement their
language-specific inheritance hierarchies while still exploiting the
mechanism provided by JS.
I do want to intend to put some further though into the details of how
I've specified this, but I think it is a capability that we need.
Allen
[1]:
https://github.com/allenwb/ESnext-experiments/blob/master/ST80collections-exp1.js#L90
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss