Le 07/03/2012 02:10, Brandon Benvie a écrit :
> I start this coming from the standpoint of an honest question that I
> don't know the answer to: is there a specific reason that objects
> can't be callable in js? Aside from the "that's just how the language
> is" answer, I was wondering if there's some other computer sciency or
> performance reason for the restriction.
One further detailled explanation of "that's just how the language work"
would be that a JavaScript invariant is that a value has a stable result
to "typeof". So it's impossible to change a non-callable object into a
callable object without breaking this invariant (as stated by ES5, a
callable object has "function" for it's typeof value while non-callable
objects have "object").
Besides this, I don't see a restriction on why you couldn't just use
functions each time you need an object.
> I've had this question a number of times but the most recent spart was
> seeing this from Allen Wirfs-Brock:
>
>> //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)}
>> }
>> };
> As it is currently, the behavior of a function is that it defaults to
> be a `constructor-like`. It has a prototype that it bestows upon
> objects JS tells it to create, and it's not even possible for it to
> have no prototype property. I would imagine a callable object is more
> like a non-constructor function (something like isNaN) or, currently,
> it's essentially the same as doing `object.valueOf()`. In fact there's
> nothing stopping one from making every single object they use (aside
> from an array) callable simply by starting with a function literal and
> assigning its __proto__.
However, you do not need to use functions as constructors.
I wish block lambda [1] to be adopted for ES6. I think they would fit
your vision of functions, because it certainly wouldn't make sense to
construct with them and they would certainly have no use of a
'prototype' property.
Hopefully, it will be possible to combine block-lambda with the <|
operator to create callable objects with arbitrary prototype.
> (...)
> Partilly this is resolved with ES6, as is the arraylikes problem.
Indeed. All the "change the prototype at object creation time" was the
rational behind the <| operator (and as you note, it will work for
arrays, and functions and most things)
David
[1] http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss