On Mar 27, 2012, at 11:59 AM, Brendan Eich wrote:
> Russell Leggett wrote:
>> Can we make it writable:false, configurable:true? Of course, that would only
>> be a minor deterrent from changing it around, but maybe just enough?
>
> This has zero integrity, so is IMHO worse than worthless -- it's misleading.
> Not that anyone will count on it, but stopping assignments while allowing
> reconfiguration or deletion and redefinition does not smell right.
I think {writeable: false, configurable: true} is, in general, a great
attribute combination. That's why I keep spec'ing things to use it. It isn't
about integrity guarantees. It's about reinforcing the intended normal
application level usage intent of a feature while preserving the ability
perform reflective metaprogramming. It is about more clearly stratify the
application and meta levels of ES. It's about = keeping straight which strata
= belongs in.
JavaScript has always (I assume) allowed = to be used to create properties.
var obj = {};
obj.x = 42;
obj.y = functionI) {return this.x*2};
The problem with such assignments is there is no clue whether x and y intended
to used fixed data members of the object, expando data members, dynamic keys of
a hash map data structure, or in the case of y is it a method or simply a data
element with a first class function value. y even shows up in for-in data
element enumerations (we infer from array behavior that for-in was intended to
iterate over the data elements of an object and not the behavioral elements (eg
methods).
But if I use concise method definitions in object literals or class
declarations (or Object.defineMethod) I'm making a stronger statement about
function valued properties. I'm explicitly saying that these properties are to
be treated as behavioral elements not as data elements. Setting the attributes
of concisely defined methods to {enumerable: false, writable:false,
configurable: true} helps me guide the users of abstraction into usage patterns.
By setting writable: false we are saying, don't use the assignment operator to
modify the value of this property. It isn't data. If you try to, the assignment
will be ignored (or throw in strict mode). This applies whether you are
directly accessing such a method on an object created by an object literal or
operating upon an instance that is inheriting the property from a prototype.
However, it does "freeze" the method. If you need to do meta programing
involving such methods you still can. You just have to use
Object.defineProperty/defineMethods. You have to act like you know what you are
doing if you want to manipulate a property that has been explicitly declared as
a method.
>
> To answer Dave's question, I meant that classes without any extra
> Object.defineProperty calls can be used to implement built-ins. Not a huge
> win but seemingly better than requiring Object.defineProperty for that case
> -- assuming class declarations create a constructor property on the class
> prototype.
Chapter 15 built-ins have prototype.constructor that are writable and
configurable. It is the prototype property that is non-writable and
non-configurable for built-in constructors.
>
> If we want class C {} to create no C.prototype.constructor back-link to C,
> then we're not sugaring the prototypal pattern. That seems like too much
> innovation instead of desugaring, but you could model it via delete
> C.prototype.constructor after class C{} assuming constructor is configurable.
In all the discussion about deleting (or not having) a "constructor" property
on the prototype, I think people are over-looking (I haven't seen it mentioned)
that if a subclass is going to do a super constructor call (whether the name
"constructor" is syntactically explicit or implicit) then their better damn
well be a property named "constructor" somewhere above it on the [[Prototype]]
chain.
>
> Of course one could argue based on desugaring to user-defined (not built-in)
> functions that C.prototype.constructor should be configurable and writable:
This is actually how the the maximally minimal class strawman currently defines
it and for exactly the reason that it is what function() {} does. However,
this thread has actually convinced me that it probably should be configurable
and non-writable (and, of course, non-enumerable).
We shouldn't want to see this:
class C () {
... //methods
}
C.prototype.constructor = null;
if somebody has a good enough reason for this they should mean it enough to say
Object.defineProperty(C.prototype,"constructor",{value: null});
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss