tc39 / proposal-static-class-features

The static parts of new class features, in a separate proposal
https://arai-a.github.io/ecma262-compare/?pr=1668
127 stars 27 forks source link

Access from this should be supported #62

Open earonesty opened 4 years ago

earonesty commented 4 years ago

Allowing statics and functions of the same name is currently how the babel plugin works. I suspect this is confusing. IE:

This should work.

class Foo {
   static flag = 4
   logFlag() {
       console.log(this.flag)
   }
}

This should be a syntax error:

class Foo {
   static flag = 4
   flag() {
       console.log(Foo.flag)
   }
}
ljharb commented 4 years ago

In your first example, there's Foo.flag === 4 and Foo.prototype.logFlag, which would log undefined. What's not working for you in that one?

In the second example, since there's no conflict between Foo.flag and Foo.prototype.flag, why should that be a syntax error? You can already do this:

class Foo {
  static get flag() {}
  flag() {}
}

so it'd be very confusing imo if your second example errored.

invader-viim commented 4 years ago

Allowing statics and functions of the same name is currently how the babel plugin works. I suspect this is confusing. IE:

This should work.

class Foo {
   static flag = 4
   logFlag() {
       console.log(this.flag)
   }
}

This should be a syntax error:

class Foo {
   static flag = 4
   flag() {
       console.log(Foo.flag)
   }
}

if it's a "static" property it should never be accessible from "this" i would think, the idea of it being static means those properties and methods are not available within the instantiated class thus no "this".

caiolima commented 3 years ago

Hi @earonesty.I didn't understand the problem this issue reports. Do you mind explaining a bit further?

wentout commented 3 years ago

Let assume we have simple function. We can join a field to the reference, and that mean static from the early beginning of JS.

var Foo = function () {
    console.log(this.flag === undefined); // true
    console.log(Foo.flag === 4); // true
};
Foo.flag = 4;

So, is this OK if we will change this behavior for classes? If so then we will be able to change flag field from any of inside of the constructor. And also we will be able to change it from super pointer. And, what if we use Proxy for something nested in Prototype Chain, how Reflect will work then?

The way it should retrieve an access is an explicit access through .constructor property:

class Foo {
    static flag = 4
    constructor() {
        // explicit access
        // no hidden behavior
        // thinking of code review
       console.log(this.constructor.flag);
   }
}

My hope this will never see static field directly.

ljharb commented 3 years ago

@wentout That example will work, as would the better practice of not relying on .constructor and hardcoding Foo.flag. Use of Proxy shouldn't change anything.