Typeof this in getters (was: eval on non-strings)

# Domenic Denicola (14 years ago)

Specifically regarding ToObject. It's use is important in minimizing the semantic differences between primitive values and Objects. In ES5 we eliminated the automatic wrapping of primitive values used as this values in method invocations. That means that in most cases 42 and (new Number(42)) can be used interchangeably. If we start leaving out ToObject calls in random places the distinction between a primitive value and a wrapped primitive values will start tripping people up.

This actually is apropos of something I'd been meaning to ask about. Consider the following JSFiddle:

jsfiddle.net/CxdMs/15

It seems reasonably clear that the result for functions should be object (non-strict)/number (strict), according to section 10.4.3.

But for getters, the major browsers disagree, and my spec-fu can't find anything besides the abovementioned section. Firefox and IE9 say object/object, while V8 says number/number. And at least one version of JavaScriptCore we have lying around says number/object. If someone could walk me through the spec correctly, I'd be happy to file appropriate browser bugs.

Note that this is a real-world issue. The Chai.js assertion library is trying to break free of V8 and become useful in browsers, but is encountering problems due to this behavior:

logicalparadox/chai#32

Thanks all, Domenic

# Mark S. Miller (14 years ago)

I like the output display on jsfiddle.net/CxdMs/16 a bit better. I just tried it on very recent versions of 4 or the 5 major browsers. I was shocked to see that all of them were wrong.

Correct would be

number      number
object        object

Chrome 19 gave

number      number
object        number

Opera 12, Safari WebKit 5.1.3 (7534.53.10, r109097), and Mozilla FF Nightly 13 all gave

number      object
object        object

What does the latest IE10 preview do?

Domenic, as you post bugs against the browsers, please send me the URLs. Thanks.

# Oliver Hunt (14 years ago)

On Feb 28, 2012, at 11:38 AM, Mark S. Miller wrote:

I like the output display on jsfiddle.net/CxdMs/16 a bit better. I just tried it on very recent versions of 4 or the 5 major browsers. I was shocked to see that all of them were wrong.

Correct would be

number      number
object        object

Chrome 19 gave

number      number
object        number

Opera 12, Safari WebKit 5.1.3 (7534.53.10, r109097), and Mozilla FF Nightly 13 all gave

number      object
object        object

We consider this a bug in JSC, in the great "make |this| correct" refactoring of 2011 we missed the getter/setter entries manually performing this conversion prior to calling the function proper...

# Rick Waldron (14 years ago)

On Tue, Feb 28, 2012 at 2:42 PM, Oliver Hunt <oliver at apple.com> wrote:

On Feb 28, 2012, at 11:38 AM, Mark S. Miller wrote:

I like the output display on jsfiddle.net/CxdMs/16 a bit better. I just tried it on very recent versions of 4 or the 5 major browsers. I was shocked to see that all of them were wrong.

Correct would be

number      number
object        object

I went to refresh myself on this and thought others might be interested in reading the same: es5.github.com/#this

# Allen Wirfs-Brock (14 years ago)

On Feb 28, 2012, at 10:03 AM, Domenic Denicola wrote:

Specifically regarding ToObject. It's use is important in minimizing the semantic differences between primitive values and Objects. In ES5 we eliminated the automatic wrapping of primitive values used as this values in method invocations. That means that in most cases 42 and (new Number(42)) can be used interchangeably. If we start leaving out ToObject calls in random places the distinction between a primitive value and a wrapped primitive values will start tripping people up.

This actually is apropos of something I'd been meaning to ask about. Consider the following JSFiddle:

jsfiddle.net/CxdMs/15

It seems reasonably clear that the result for functions should be object (non-strict)/number (strict), according to section 10.4.3.

10.4.3 is the applicable section. It get/set function is still "function code" so it doesn't matter what mechanism was used to call it. It still has to pass through the 10.4.3 requirements. So the correct answer is number/object.

Any other answer is not in conformance with the spec.

There there should be test262 tests for this. However I bet there aren't any, given that the two major contributors to the test suite appear to be out of conformance

# Domenic Denicola (14 years ago)

Both IE10 Developer Preview (10.0.8102.0) and IE10 Platform Preview 4 (10.0.8103.0) output

number      object
object        object

We'll see if tomorrow's drop does any better.

Sounds like I should file test262 bugs as well.

From: Mark S. Miller [mailto:erights at google.com] Sent: Tuesday, February 28, 2012 14:38 To: Domenic Denicola Cc: Allen Wirfs-Brock; Brendan Eich; es-discuss at mozilla.org Subject: Re: Typeof this in getters (was: eval on non-strings)

I like the output display on jsfiddle.net/CxdMs/16 a bit better. I just tried it on very recent versions of 4 or the 5 major browsers. I was shocked to see that all of them were wrong.

Correct would be

number      number     object        object

Chrome 19 gave

number      number     object        number

Opera 12, Safari WebKit 5.1.3 (7534.53.10, r109097), and Mozilla FF Nightly 13 all gave

number      object     object        object

What does the latest IE10 preview do?

Domenic, as you post bugs against the browsers, please send me the URLs. Thanks.

On Tue, Feb 28, 2012 at 10:03 AM, Domenic Denicola <domenic at domenicdenicola.com> wrote:

Specifically regarding ToObject.  It's use is important in minimizing the semantic differences between primitive values and Objects. In ES5 we eliminated the automatic wrapping of primitive values  used as this values in method invocations.  That means that in most cases 42 and (new Number(42)) can be used interchangeably. If we start leaving out ToObject calls in random places the distinction between a primitive value and a wrapped primitive values will start tripping people up.

This actually is apropos of something I'd been meaning to ask about. Consider the following JSFiddle:

jsfiddle.net/CxdMs/15

It seems reasonably clear that the result for functions should be object (non-strict)/number (strict), according to section 10.4.3.

But for getters, the major browsers disagree, and my spec-fu can't find anything besides the abovementioned section. Firefox and IE9 say object/object, while V8 says number/number. And at least one version of JavaScriptCore we have lying around says number/object. If someone could walk me through the spec correctly, I'd be happy to file appropriate browser bugs.

Note that this is a real-world issue. The Chai.js assertion library is trying to break free of V8 and become useful in browsers, but is encountering problems due to this behavior:

logicalparadox/chai#32

Thanks all, Domenic

# Mark S. Miller (14 years ago)

On Tue, Feb 28, 2012 at 3:38 PM, Domenic Denicola < domenic at domenicdenicola.com> wrote:

Both IE10 Developer Preview (10.0.8102.0) and IE10 Platform Preview 4 (10.0.8103.0) output

number object object object

We'll see if tomorrow's drop does any better.

yes,

# Mark S. Miller (14 years ago)

On Tue, Feb 28, 2012 at 3:38 PM, Domenic Denicola < domenic at domenicdenicola.com> wrote:

Both IE10 Developer Preview (10.0.8102.0) and IE10 Platform Preview 4 (10.0.8103.0) output

number object object object

We'll see if tomorrow's drop does any better.

Sounds like I should file test262 bugs as well.

Oops. I meant for

Yes, thanks!

to be placed here. Yes, thanks for filing test262 bugs as well.

# Dave Fugate (14 years ago)

To clarify, the expected results here are: Non-strict Typeof this inside a function when called on a number: object Typeof this inside an Object.prototype getter when used on a number: object Strict Typeof this inside a function when called on a number: number Typeof this inside an Object.prototype getter when used on a number: number right?

There's over a hundred test cases that have already been created, and will be contributed 'soon' to cover ecmascript#180. One such test case is: function foo() { 'use strict'; return typeof(this); } function bar() { return typeof(this); } return foo.call(1) === 'number' && bar.call(1) === 'object';

Another that seem relevant here is: function testcase() { var o = {}; Object.defineProperty(o, "foo", { get: function() { "use strict"; return this; } }); return o.foo===o; } On that note, is there anything that's particularly interesting spec-wise in defining foo on Object.prototype instead of a generic object and validating there?

Thanks!

Dave

From: es-discuss-bounces at mozilla.org [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Mark S. Miller Sent: Tuesday, February 28, 2012 3:45 PM To: Domenic Denicola Cc: es-discuss at mozilla.org; Brendan Eich Subject: Re: Typeof this in getters (was: eval on non-strings)

On Tue, Feb 28, 2012 at 3:38 PM, Domenic Denicola <domenic at domenicdenicola.com<mailto:domenic at domenicdenicola.com>> wrote:

Both IE10 Developer Preview (10.0.8102.0) and IE10 Platform Preview 4 (10.0.8103.0) output

number object object object

We'll see if tomorrow's drop does any better.

Sounds like I should file test262 bugs as well.

Oops. I meant for

Yes, thanks!

to be placed here. Yes, thanks for filing test262 bugs as well.

From: Mark S. Miller [mailto:erights at google.com<mailto:erights at google.com>]

Sent: Tuesday, February 28, 2012 14:38 To: Domenic Denicola Cc: Allen Wirfs-Brock; Brendan Eich; es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>

Subject: Re: Typeof this in getters (was: eval on non-strings)

I like the output display on jsfiddle.net/CxdMs/16 a bit better. I just tried it on very recent versions of 4 or the 5 major browsers. I was shocked to see that all of them were wrong.

Correct would be

number      number
object        object

Chrome 19 gave

number      number
object        number

Opera 12, Safari WebKit 5.1.3 (7534.53.10, r109097), and Mozilla FF Nightly 13 all gave

number      object
object        object

What does the latest IE10 preview do?

Domenic, as you post bugs against the browsers, please send me the URLs. Thanks.

On Tue, Feb 28, 2012 at 10:03 AM, Domenic Denicola <domenic at domenicdenicola.com<mailto:domenic at domenicdenicola.com>> wrote:

Specifically regarding ToObject. It's use is important in minimizing the semantic differences between primitive values and Objects. In ES5 we eliminated the automatic wrapping of primitive values used as this values in method invocations. That means that in most cases 42 and (new Number(42)) can be used interchangeably. If we start leaving out ToObject calls in random places the distinction between a primitive value and a wrapped primitive values will start tripping people up.

This actually is apropos of something I'd been meaning to ask about. Consider the following JSFiddle:

jsfiddle.net/CxdMs/15

It seems reasonably clear that the result for functions should be object (non-strict)/number (strict), according to section 10.4.3.

But for getters, the major browsers disagree, and my spec-fu can't find anything besides the abovementioned section. Firefox and IE9 say object/object, while V8 says number/number. And at least one version of JavaScriptCore we have lying around says number/object. If someone could walk me through the spec correctly, I'd be happy to file appropriate browser bugs.

Note that this is a real-world issue. The Chai.js assertion library is trying to break free of V8 and become useful in browsers, but is encountering problems due to this behavior:

logicalparadox/chai#32

Thanks all, Domenic

# Domenic Denicola (14 years ago)

To clarify, the expected results here are:

Non-strict Typeof this inside a function when called on a number: object Typeof this inside an Object.prototype getter when used on a number: object

Strict Typeof this inside a function when called on a number: number Typeof this inside an Object.prototype getter when used on a number: number

right?

Yes.

There’s over a hundred test cases that have already been created, and will be contributed ‘soon’ to cover ecmascript#180.  One such test case is:   function foo()   {     'use strict';     return typeof(this);   }   function bar()   {     return typeof(this);   }   return foo.call(1) === 'number' && bar.call(1) === 'object';

Chrome fails this one with bar.call(1)==='number', but everyone else passes.

Another that seem relevant here is: function testcase() { var o = {}; Object.defineProperty(o, "foo", { get: function() { "use strict"; return this; } }); return o.foo===o; }

This is irrelevant because it is not testing primitives and boxing. (More formally, it is not testing the relevant part of 10.4.3 that we are discussing.)

On that note, is there anything that’s particularly interesting spec-wise in defining foo on Object.prototype instead of a generic object and validating there?

It's relevant because it allows use on numbers, i.e. (0).getMe. The same results happen if you define on Number.prototype.