David Bruant wrote:
Le 28/07/2012 13:43, Herby Vojčík a écrit :
David Bruant wrote:
      var a = [];
      a.push = function(elem){
          if(condition(elem)){
              // do something like change the elem value then do an
actual
push
              // or throw an error
              // or just ignore this value to avoid duplicates, for
instance
          }
          else{
              Array.prototype.push.call(this, elem)
          }
      };

      // use a.push (there is an implicit contract on only using .push to
add elements)

(...)

* I could use Object.defineProperty, but the above code is definitely
more readable and intuitive.
Well, yes. But from the philosophical PoV, imho, you should do
Object.defineProperty here, because that is what you do (your intent
is not "put a value to a's push property").
My intent is "I want a custom 'push' property for this particular
array", because I'm filling the array afterwards using .push calls. I
don't know what I "should" be doing from a philosophical point of view,
but the code written above describes my intention pretty well. If I saw

To be precise, [[Put]] and [[DefineProperty]] are different intents. Dveelopers may not like it, because they used to [[Put]], but it is probably needed to distinguish them.

[[Put]] is high-level contract (a, update your 'push' facet with value), [[DefineProperty]] is low-level contract (a, add/update your slot named 'push' with value).

I am inclined to see [[Put]] used to shadow methods as an abuse of high-level interface to do low-level patching.

But of course, unless there is nice sugar, everyone uses [[Put]] since it's easier to write (and read).

a call to Object.defineProperty instead, my first reaction would
certainly be "but why isn't a regular assignment used here?". A comment
could be added to explain the [[CanPut]], but that's what I would call
"boilerplate comment".

So far, to the general question "why is Object.defineProperty used
instead of a regular assignment used here?", the only answer I find
acceptable is "defining custom configurable/writable/enumerable",
because these are things local to the code that have no syntax for them.
In most cases, getter/setters can be defined in object literals.
Adding "the prototype may be frozen, thus preventing shadowing" to the
acceptable answers makes local code review harder.

:-/ But that is how it is, no?

Though not very constructive, I'd say this is the case where

a.{
   push(elem) {
     ...
   }
};

is definitely missing.
I remembered that .{ semantics was a [[Put]] semantic, so it wouldn't
solve the problem. Did I remember something wrong?

Of course. Mustache has the same semantics as extended literal, so it was [[DefineProperty]] with appropriate enum/conf/writ (and setting home context for methods, so in fact it did defineMethod).

Arguably, I could use a different name than "push". But it doesn't
change the problem:
If I add an 'x' property to my array and later in the history of ES, an
Array.prototype.x property is added, my code will break by virtue of
engines updating... hmm... That's a worse situation than I initially
thought.

David

Herby
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to