Home > Mobile >  What is the prototype in this class?
What is the prototype in this class?

Time:10-20

In the following class:

class Range2 {
    constructor(from, to) {
        this.from = from;
        this.to = to;
    }
    toString() {
        console.log("Hello!");
        return `(${this.from}...${this.to})`
    }
    *[Symbol.iterator]() {
        for (let x = this.from; x <= this.to; x  ) yield x;
    }
    includes(x) {
        return x >= this.from && x <= this.to
    }
}
r = new Range2(1, 5);
console.log(r.toString());
console.log(r.includes(3), r.includes(7));

What is the prototype of this Range2 class? I know the constructor allow building object. I'm familiar with Python and so it's the same as the __init__ :

class Range2:
    def __init__(self, from, to):
        self.from = from
        self.to = to

But what is the prototype, and the closest equivalent in Python if there is one?

CodePudding user response:

So the class syntax is functionally the same as:

function Range(from, to){
  this.from = from;
  this.to = to;
}

Range.prototype = {
  toString(){
    console.log("Hello!");
    return `(${this.from}...${this.to})`;
  },
  *[Symbol.iterator](){
    for (let x = this.from; x<=this.to; x  ) yield x;
  },
  includes(x){
    return x>=this.from && x<=this.to;
  }
}

r = new Range(1, 5);
console.log(r.toString());
console.log(r.includes(3), r.includes(7));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

The constructor function is created and the prototype is assigned to that constructor. Then, when we call new Range(1, 5), we create an empty object, we use the Range function to construct that object, and we link its prototype to the Range.prototype. This is all being done for us by the new keyword.

The class version is doing the exact same thing we've done here using a function/prototype, it's simply happening behind the scenes. So other than the fact I named mine Range and yours is Range2, they do exactly the same thing.

Javascript is quite different from most class-based languages, and there are gotchas. Prototypal inheritance is defining an event delagate, rather than a true "parent class".

CodePudding user response:

You asked:

What is the prototype of this Range2 class?

That question appears to me to be the same as the question "What is the prototype of the entity bound to the variable Range2?" The answer to that question is:

Function.prototype

which is the prototype of any object that is a function, and classes are functions in JavaScript. Here's a Node console session that shows this:

$ node
> class C {}
undefined
> typeof C
'function'
> Object.getPrototypeOf(C) === Function.prototype
true

If your question is "What will be the prototype assigned to all instances of objects I create of the class Range2 then the answer would be:

Range2.prototype

since, as others have mentioned, Range2 is just a function. And user Snowmonkey has shown the contents of this object.

Your question mentioned something about a constructor and you are looking for something similar to Python's __init__. Interestingly, JavaScript's notion of a constructor for a class turns out to be the function itself! And a reference to this function is stored in the prototype property of the function. Back in our console:

> C.prototype.constructor === C
true

It seems crazy perhaps, but it is quite powerful and useful. It allows dynamic lookup, for any object, of the function that created it. And since classes are factories for instances, it totally makes sense. Back in the console:

> const c = new C()
> c.constructor
[class C]
> c.constructor === C
true

In a way, an object's .constructor property is a lot like Python's type function. JavaScript's typeof operator can only return a string representation of a handful of dynamic types, including "object" - so the constructor property turns out to be useful, if you find yourself querying types at run time (which is probably a dubious thing to do often).

  • Related