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).