Implicit this value for getters and setters on the global object

# Claude Pache (9 years ago)

Consider the following test case:

<script>

function returnThisValue() { "use strict"; return this }

Object.defineProperties(Object.prototype, {
    getThisValue: { value: returnThisValue, configurable: true }
  , thisValue: { get: returnThisValue, configurable: true }
})

window.alert(getThisValue() + "\n" + thisValue)

</script>

What should be displayed? According to my tests:

  • Firefox [1], Chrome and Edge:

    undefined [object Window]

[1]: (For Firefox, use v.46+ in order to avoid interference with this recently-solved bug: bugzilla.mozilla.org/show_bug.cgi?id=603201, bugzilla.mozilla.org/show_bug.cgi?id=603201)

  • Safari (although I get contradictory results with further tests involving __proto__):

    undefined undefined

  • ECMA-262, if I read correctly:

    undefined [object Window]

The relevant steps in the spec are:

  • for getThisArg() : 12.3.1.4.1 step 4.b.ii, where refEnv is an Object Environment Record associated to the global object; refEnv.WithBaseObject() will be undefined.
  • for thisArg: 8.1.1.2.6 step 5, where bindings is the global object and N is "thisArg".

Is it an intentional and/or desired behaviour?

In practice it has an influence on what a bare __proto__ should evaluate to.

# Allen Wirfs-Brock (9 years ago)

On Mar 3, 2016, at 10:57 AM, Claude Pache <claude.pache at gmail.com> wrote:

Hi,

Consider the following test case:

<script>

function returnThisValue() { "use strict"; return this }

Object.defineProperties(Object.prototype, {
    getThisValue: { value: returnThisValue, configurable: true }
  , thisValue: { get: returnThisValue, configurable: true }
})

window.alert(getThisValue() + "\n" + thisValue)

</script>

What should be displayed? According to my tests:

  • Firefox [1], Chrome and Edge:

    undefined [object Window]

[1]: (For Firefox, use v.46+ in order to avoid interference with this recently-solved bug: bugzilla.mozilla.org/show_bug.cgi?id=603201, bugzilla.mozilla.org/show_bug.cgi?id=603201)

  • Safari (although I get contradictory results with further tests involving __proto__):

    undefined undefined

  • ECMA-262, if I read correctly:

    undefined [object Window]

The relevant steps in the spec are:

  • for getThisArg() : [12.3.1.4.1] step 4.b.ii, where refEnv is an Object Environment Record associated to the global object; refEnv.WithBaseObject() will be undefined.
  • for thisArg: [8.1.1.2.6] step 5, where bindings is the global object and N is "thisArg".

[12.3.1.4.1]: tc39.github.io/ecma262/#sec-function-calls-runtime-semantics-evaluation, tc39.github.io/ecma262/#sec-function-calls-runtime-semantics-evaluation [8.1.1.2.6]: tc39.github.io/ecma262/#sec-object-environment-records-getbindingvalue-n-s, tc39.github.io/ecma262/#sec-object-environment-records-getbindingvalue-n-s

Is it an intentional and/or desired behavior?

Get accessors on the global object have been defined with this behavior since ES5, when accessor properties were introduced. It was intentional that global variable access has the semantics of [[Get]]/[[Set]] accesses to the corresponding property of the global object.

In practice it has an influence on what a bare __proto__ should evaluate to.

How so? As currently specified bare __proto__ does a get/setPrototypeOf the global object that is in scope.

# Claude Pache (9 years ago)

Le 4 mars 2016 à 00:57, Allen Wirfs-Brock <allen at wirfs-brock.com> a écrit :

On Mar 3, 2016, at 10:57 AM, Claude Pache <claude.pache at gmail.com <mailto:claude.pache at gmail.com>> wrote:

Hi,

Consider the following test case:

<script>

function returnThisValue() { "use strict"; return this }

Object.defineProperties(Object.prototype, {
    getThisValue: { value: returnThisValue, configurable: true }
  , thisValue: { get: returnThisValue, configurable: true }
})

window.alert(getThisValue() + "\n" + thisValue)

</script>

What should be displayed? According to my tests:

  • Firefox [1], Chrome and Edge:

undefined [object Window]

[1]: (For Firefox, use v.46+ in order to avoid interference with this recently-solved bug: bugzilla.mozilla.org/show_bug.cgi?id=603201, bugzilla.mozilla.org/show_bug.cgi?id=603201)

  • Safari (although I get contradictory results with further tests involving __proto__):

undefined undefined

  • ECMA-262, if I read correctly:

undefined [object Window]

The relevant steps in the spec are:

  • for getThisArg() : [12.3.1.4.1] step 4.b.ii, where refEnv is an Object Environment Record associated to the global object; refEnv.WithBaseObject() will be undefined.
  • for thisArg: [8.1.1.2.6] step 5, where bindings is the global object and N is "thisArg".

[12.3.1.4.1]: tc39.github.io/ecma262/#sec-function-calls-runtime-semantics-evaluation, tc39.github.io/ecma262/#sec-function-calls-runtime-semantics-evaluation [8.1.1.2.6]: tc39.github.io/ecma262/#sec-object-environment-records-getbindingvalue-n-s, tc39.github.io/ecma262/#sec-object-environment-records-getbindingvalue-n-s

Is it an intentional and/or desired behavior?

Get accessors on the global object have been defined with this behavior since ES5, when accessor properties were introduced. It was intentional that global variable access has the semantics of [[Get]]/[[Set]] accesses to the corresponding property of the global object.

In practice it has an influence on what a bare __proto__ should evaluate to.

How so? As currently specified bare __proto__ does a get/setPrototypeOf the global object that is in scope.

One could want (or, at least, find logical) that the corresponding getter/setter receives undefined as its this-value, so that evaluating __proto__ would throw a TypeError ("cannot convert undefined to object"). Just like calling valueOf() does.