Assignment to wrapper objects in strict mode

# Andreas Rossberg (11 years ago)

Apparently, there has been a semantic change between ES5 and ES6 regarding assignment to wrapper objects in strict mode. That is,

'use strict'; "".x = 0

would throw in ES5, but AFAICS, no longer does in ES6. Was this change discussed? What is the rationale?

(FWIW, current implementations disagree about this: e.g., V8 and SM don't throw, JSC does.)

# André Bargull (11 years ago)

Apparently, there has been a semantic change between ES5 and ES6 regarding assignment to wrapper objects in strict mode. That is,

'use strict'; "".x = 0

would throw in ES5, but AFAICS, no longer does in ES6. Was this change discussed? What is the rationale?

(FWIW, current implementations disagree about this: e.g., V8 and SM don't throw, JSC does.)

/Andreas

That assignment still throws per the current ES6 draft. Following 6.2.3.2 PutValue to 9.1.9 [[Set]], step 4.d in [[Set]] creates a dummy data descriptor when no inherited property was found (that way the condition in step 5 will evaluate to true), and step 5.b in [[Set]] returns false if the receiver is not an object. At that point we're back in PutValue, and step 6.d in PutValue will now throw TypeError in strict mode.

  • André
# Andreas Rossberg (11 years ago)

On 28 May 2014 13:41, André Bargull <andre.bargull at udo.edu> wrote:

Apparently, there has been a semantic change between ES5 and ES6 regarding assignment to wrapper objects in strict mode. That is,

'use strict'; "".x = 0

would throw in ES5, but AFAICS, no longer does in ES6. Was this change discussed? What is the rationale?

(FWIW, current implementations disagree about this: e.g., V8 and SM don't throw, JSC does.)

That assignment still throws per the current ES6 draft. Following 6.2.3.2 PutValue to 9.1.9 [[Set]], step 4.d in [[Set]] creates a dummy data descriptor when no inherited property was found (that way the condition in step 5 will evaluate to true), and step 5.b in [[Set]] returns false if the receiver is not an object. At that point we're back in PutValue, and step 6.d in PutValue will now throw TypeError in strict mode.

But base will already have been converted to a wrapper object at PutValue step 6.a.ii before you get to [[Set]].

# André Bargull (11 years ago)

On 5/28/2014 2:00 PM, Andreas Rossberg wrote:

On 28 May 2014 13:41, André Bargull <andre.bargull at udo.edu> wrote:

Apparently, there has been a semantic change between ES5 and ES6 regarding assignment to wrapper objects in strict mode. That is,

'use strict'; "".x = 0

would throw in ES5, but AFAICS, no longer does in ES6. Was this change discussed? What is the rationale?

(FWIW, current implementations disagree about this: e.g., V8 and SM don't throw, JSC does.)

That assignment still throws per the current ES6 draft. Following 6.2.3.2 PutValue to 9.1.9 [[Set]], step 4.d in [[Set]] creates a dummy data descriptor when no inherited property was found (that way the condition in step 5 will evaluate to true), and step 5.b in [[Set]] returns false if the receiver is not an object. At that point we're back in PutValue, and step 6.d in PutValue will now throw TypeError in strict mode.

But base will already have been converted to a wrapper object at PutValue step 6.a.ii before you get to [[Set]].

/Andreas

The receiver argument in [[Set]] is not the wrapped base, but GetThisValue(V), here: the empty string "".

# Andreas Rossberg (11 years ago)

On 28 May 2014 14:08, André Bargull <andre.bargull at udo.edu> wrote:

On 5/28/2014 2:00 PM, Andreas Rossberg wrote:

On 28 May 2014 13:41, André Bargull <andre.bargull at udo.edu> wrote:

Apparently, there has been a semantic change between ES5 and ES6 regarding assignment to wrapper objects in strict mode. That is,

'use strict'; "".x = 0

would throw in ES5, but AFAICS, no longer does in ES6. Was this change discussed? What is the rationale?

(FWIW, current implementations disagree about this: e.g., V8 and SM don't throw, JSC does.)

That assignment still throws per the current ES6 draft. Following 6.2.3.2 PutValue to 9.1.9 [[Set]], step 4.d in [[Set]] creates a dummy data descriptor when no inherited property was found (that way the condition in step 5 will evaluate to true), and step 5.b in [[Set]] returns false if the receiver is not an object. At that point we're back in PutValue, and step 6.d in PutValue will now throw TypeError in strict mode.

But base will already have been converted to a wrapper object at PutValue step 6.a.ii before you get to [[Set]].

The receiver argument in [[Set]] is not the wrapped base, but GetThisValue(V), here: the empty string "".

Ah, you are right, thanks. Sorry for the noise.