actually `writable:false` is OK, it's only the `get` case that is buggy, as
well as `set`

on Android 2.3.6 (or lower) you can [try this page](
http://www.3site.eu/jstests/configurable.html) which will show an alert like

```
4,     // the length
true, // has enumerable bug
OK,  // code works anyway deleting in proto
456, // test value is correct
      // probably undefined, no idea why is empty
      // but the value is not there
```

last test is something like
`Object.create(Object.defineProperty({},'test',{set:Object}),{test:{value:456}}).test`
which won't show `456` in these devices ... it actually does nothing, not
even throwing, it's just undefined.

So, whatever decision will be taken about not writable, if you want to
consider old browsers .. these are ok with `writable:false` because it's
possible to reconfigure them without needing to delete the prototype first.

Sorry for the initial false alarm, at least I am sure few didn't know about
the getters and setters bug in actually quite recent Android 2 browsers.

Best Regards














On Wed, Mar 26, 2014 at 2:10 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> I am not sure I understood: is not throwing and a silent failure
> preferred? 'cause that method won't be there anyway...
>
> I need to write chapter 3 of my quadrilogy of posts related to descriptors
> and inheritance* but you can "simply" avoid that problem via
> `Object.defineProperty(Pony.prototype, 'toString', {value: function () {}})`
>
> This will most likely work everywhere except in old mobile browsers such
> Palm Pre and Android 2.2 or 2.3, cannot remember, where this bug will show
> up:
>
> ```javascript
> var hasConfigurableBug = !!function(O,d){
>   try {
>     O.create(O[d]({},d,{get:function(){
>       O[d](this,d,{value:d})
>     }}))[d];
>   } catch(e) {
>     return true;
>   }
> }(Object, 'defineProperty');
> ```
>
> Accordingly, with these browsers the following code will fail:
> ```javascript
> Object.defineProperty(Function.prototype, 'test', {
>   get: function () {
>     return Object.defineProperty(this, 'test', {
>       value: 'OK'
>     }).test;
>   }
> });
> ```
>
> but not this one:
> ```javascript
> var proto = {};
> Object.defineProperty(proto, 'test', {
>   get: function () {
>     if (hasConfigurableBug) {
>       var descriptor = Object
>         .getOwnPropertyDescriptor(proto, 'test');
>       delete proto.test;
>     }
>     Object.defineProperty(this, 'test', {
>       value: 'OK'
>     });
>     if (hasConfigurableBug) {
>       Object.defineProperty(proto, 'test', descriptor);
>     }
>     return this.test;
>   }
> });
> ```
>
> The key is keep properties configurable so that these can be deleted and
> put back later on ... although this goes against that feeling of security
> `Object.freeze(Object.prototype)` or `Object.freeze(global)` gives us ...
> but I still believe that few edge cases a part these operations should be
> avoided.
>
> Anyway, please update this thread whenever a decision has been taken so I
> can point to this one in one of these posts.
>
> * [part 1](
> http://webreflection.blogspot.com/2014/03/what-books-wont-tell-you-about-es5.html
> )
>   [part 2](
> http://webreflection.blogspot.com/2014/03/what-books-didnt-tell-you-about-es5.html
> )
>
> part 3 with solutions to this problem coming soon
>
>
>
> On Wed, Mar 26, 2014 at 11:24 AM, Jason Orendorff <
> jason.orendo...@gmail.com> wrote:
>
>>     "use strict";
>>     function Pony() {}
>>     Object.freeze(Object.prototype);
>>     Pony.prototype.toString = function () { return "Pony"; };
>>
>> The last line here throws a TypeError in ES5 and ES6.*  Can we change
>> it? To me, it stands to reason that you should be able to freeze
>> Object.prototype and not break your other code, as long as that code
>> doesn't actually try to modify Object.prototype.
>>
>> This bit some Mozilla hackers in <http://bugzil.la/980752>.
>>
>> Compatibility: Changing from throwing to not-throwing is usually ok.
>> In addition, I don't think Chrome implements this TypeError. So
>> presumably the web can't be depending on the exception.
>>
>> Patch: Step 5.a of [[Set]] could be changed like from:
>>     a. If ownDesc.[[Writable]] is false, return false.
>> to:
>>     a. If ownDesc.[[Writable]] is false and O and Receiver are the
>> same object, return false.
>>
>> -j
>>
>>
>> *Why I think it throws:
>>
>>
>> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver
>>
>> Pony.prototype.[[Set]] reaches step 4.c. and tail-calls
>> Object.prototype.[[Set]], which reaches step 5.a. and returns false.
>>
>> The TypeError is thrown from step 6.d. of PutValue:
>> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-putvalue
>>
>> which is called from step 1.f. from AssignmentExpression Evaluation:
>>
>> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-assignment-operators-runtime-semantics-
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to