Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 class / instance properties

This is going to be a relatively long question, but one I would really like to understand. Final question formulated at the bottom of the question.

I have read the answers to this question:
ES6 class variable alternatives

The question on why this is not accepted syntax in ES6:

class MyClass {
    const MY_CONST = 'string';
    constructor(){
        this.MY_CONST;
    }
}

1) The first answer mentions:

Remember, a class definition defines prototype methods - defining variables on the prototype is generally not something you do.

I don't get this; static variables in a class based language would appear to serve the same purpose as properties defined on the prototype in JS.
Obviously not an instance variable like a person's name, but it could be a default MAX_SPEED for a vehicle, or a counter that is shared by all instances. If the instance doesn't override the prototype's MAX_SPEED, it returns to the default. Isn't that the exact purpose of a static variable?

2) The following post (ES6 spec proposal) formulates:

There is (intentionally) no direct declarative way to define either prototype data properties (other than methods) class properties, or instance property. Class properties and prototype data properties need be created outside the declaration.

I don't see the actual difference in declaring / initialising an instance/class variable with default value within the class itself (outside the constructor)? What does it matter if it's on the prototype? If it concerns an instance variable with a default value that will be likely for all instances (yet overridable), I don't see what is the problem. So what is this intention about exactly?

3) The second answer on the question ES6 class variable alternatives confuses me (though not from a technical pov).

From within a class method that variable can be accessed as this.constructor.foo (or MyClass.foo).

These class properties would not usually be accessible from to the class instance. i.e. MyClass.foo gives 'bar' but new MyClass().foo is undefined

This indicates that it is clearly possible to declare a class variable on the class (or underlying function) as implemented in this example: http://www.es6fiddle.net/iehn0hxp/

class Car{
  constructor(){
    //Set instance variable 
    this.instance_var = 220; 
    //Set class variable 
    this.constructor.class_var = 240; 
  }
}

var Mercedes = new Car(); 
var Audi = new Car(); 

//Instance property 
console.log(Mercedes.instance_var); //220 
//Class property 
console.log(Car.class_var); //240

//Set instance property 
Mercedes.instance_var = 120; //Well I don't know really :-) 
console.log(Mercedes.instance_var); //120 

//Class property 
Car.class_var = 140; 
console.log(Car.class_var); //140 
//Can be accessed from the constructor property on the instance
console.log(Mercedes.constructor.class_var); //140 
console.log(Audi.constructor.class_var); //140 

So in the end it is possible to declare a static property from within the class; so I don't see what is the difference declaring it within the constructor, versus just defining it on the class, vs defining it from outside? In the end it just seems to be a trivial technical modification to put it in the constructor vs as an actual class definition (the result will be the same).

Is it really just a design choice to only make methods available?
Ultimate question:

Because I don't understand how being a prototype-language changes the philosophy of having properties on the prototype against static variables on a class. It looks the same to me.

I hope that my question is clear, shout if not.

like image 966
html_programmer Avatar asked Sep 13 '15 01:09

html_programmer


People also ask

Can JavaScript classes have properties?

“Class fields” is a syntax that allows to add any properties. For instance, let's add name property to class User : class User { name = "John"; sayHi() { alert(`Hello, ${this.name}!`); } } new User().

What is instance property in JavaScript?

Instance properties are those properties that are defined inside any class and require an instance that is created with the help of the class name itself. Without creating the instance of the class, we may not be able to access these properties which are defined inside the class.

What are classes in ES6?

There are two types of Class in ES6: parent class/super class: The class extended to create new class are know as a parent class or super class. child/sub classes: The class are newly created are known as child or sub class. Sub class inherit all the properties from parent class except constructor.

What is super () in JavaScript?

The super keyword is used to access properties on an object literal or class's [[Prototype]], or invoke a superclass's constructor. The super. prop and super[expr] expressions are valid in any method definition in both classes and object literals.


1 Answers

I don't get this; static variables in a class based language would appear to serve the same purpose as properties defined on the prototype in JS.

No, static variables are more like properties defined on the constructor. Variables on the prototype would be closer to instance variables, but they’re not nearly as useful because they’re shared between instances. (So if you modify a mutable property on the prototype, it will be reflected in all other instances of that type.)

This also answers your other questions, I think, but to recap:

  • variables on the prototype are not like static variables in that they appear to belong to every instance rather than just the class

  • variables on the prototype are not like instance variables in that each instance of the class doesn’t have its own instance of the variable

  • therefore, variables on the prototype are not that useful and they should be assigned to in the constructor (instance variables) or assigned to the constructor (class variables)

  • they’re also properties, not variables

And a non-ES6-sugared example:

function Something() {
    this.instanceProperty = 5;
}

Something.staticProperty = 32;

Something.prototype.prototypeProperty = 977;

var s = new Something();
console.log(s.instanceProperty); // 5
console.log(s.prototypeProperty); // 977? If you want a class property,
                                  // this is not what you want
console.log(s.staticProperty); // undefined; it’s not on the instance
console.log(Something.staticProperty); // 32; rather, it’s on the class
console.log(Something.prototypeProperty); // undefined; this one isn’t
like image 96
Ry- Avatar answered Oct 21 '22 04:10

Ry-