On Jan 31, 2012, at 4:23 PM, Nebojša Ćirić wrote:
> 31. јануар 2012. 15.50, Norbert Lindenberg <[email protected]>
> је написао/ла:
> I can imagine doing this for Collator.prototype.compare because
> Array.prototype.sort is such a common use case for it, but why for the
> format() methods?
I think there is a straightforward design rule to apply in deciding whether
such a property should be a unbound method or a bound function.
If the value of the property is a function that is dependent upon the state of
its access object and the function is likely to be routinely invoke as a
standalone function then use a bound (or otherwise closed over the object)
function as the property value.
More simply, if the property is routinely accessed with an expression like:
obj.prop
then it should be a bound function. If it is routinely accessed with an
expression like:
obj.prop()
then it can be a normal method.
We have a good use case for Collator.compare that strongly suggests it should
be bound:
array.sort(col.compare)
Do we have comparable use cases for Formatter.format?
>
> I heard a couple of reasons for format methods to be bound:
>
> 1. Can be passed as functions, thus hiding the object details
would this be routinely done? If so it is a strong use case for a bound
function
displayDate(dt, mdyFmtr.format)
> 2. Makes it symmetrical to compare (in case we follow Allen's advice)
symmetry is only important if the use cases of the two functions are
similar. I assume that booth Collator and Formatter have plenty of properties
that are normally invoked as regular methods.
> 3. No binding gotchas for users
There are always gotchas if you try to dissociate a function that has (explicit
or implicit,if built-in) this reference dependencies. That is the reason for
the above design rule. Retrieving a bound function is a different logical
operation than extracting a method implementation as an reflective operation.
>
> We don't want to impose the overhead of creating a bound function on each
> call to format() unless there's a good reason...
>
> Would caching first one resolve the overhead, like so (not sure about syntax):
Yes, you would definitely want to memoize the function on first access or
perhaps even upon object creation.
>
> NumberFormat.prototype = {
> get format(date) {
> var that = this;
> if (that.__bound === undefined)
> that.__bound = function(a) { uses that; return a < b };
> return that.__bound;
> }
> }
Yes, logically. However a built-in implementation would use a private internal
state variable [[CompareFunction]] instead of a regular property. An ES6
implementation in ECMAScript would use a private name property.
Alternatively, you could simply create the bound function when you instantiate
the Format instancet object and make it the value of the format (in this
example) own property of the new instance. However, that technique would
create issues if anybody ever wants to do prototypal inheritance from such an
instance. For that reason, I would stick with the accessor on the prototype
pattern.
>
> Of course, doing it for one and not the other is somewhat inconsistent. And
> since ES 5 has Function.prototype.bind (implemented in the leading browsers
> except Safari), it's not hard to bind compare() without library support:
> myArray.sort(collator.compare.bind(collator));
>
Do you really want a naive HTML coder to have to remember this pattern?
> Yes, we should probably pick one or the other - go jQuery route and force
> developers to .bind manually, or any other library where they either bind for
> the users or provide two versions of the same method (one bind the other one
> not).
For these cases, I don't see why you would need the unbound method. Such a
unbound method is really only useful it you are going to move it to another
object and this isn't any particular reason why that should be expected to work
in this scenario. Even though the function is bound you can still say:
col.compare(a,b)
if you want to invoke it using a method invocation style
Allen_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss