class Circle { constructor(radius) { this.radius = radius; Circle.circlesMade++; }; static draw(circle, canvas) { // Canvas drawing code }; static get circlesMade() { return !this._count ? 0 : this._count; }; static set circlesMade(val) { this._count = val; }; area() { return Math.pow(this.radius, 2) * Math.PI; }; get radius() { return this._radius; }; set radius(radius) { if (!Number.isInteger(radius)) throw new Error("Circle radius must be an integer."); this._radius = radius; }; }
Object.create
API, which makes it easy to do something like this: var proto = { value: 4, method() { return 14; } } var obj = Object.create(proto); obj.value; // 4 obj.method(); // 14
obj
with the same name as proto
, they overlap ( shadow ) the original ones. obj.value = 5; obj.value; // 5 proto.value; // 4
constructor
method in the definition (definition) of the class that contains all the static methods. We also create an object that will be the property of the function we have created and which will contain all the methods of the instance (instance) of the class. To create a new class that inherits all static properties, we must force the new function object to inherit from the function object of the superclass. Similarly, we need to force the prototype
object of a new function to inherit from the prototype
superclass to ensure that class instance methods inherit.Shape
for which we want to create a subclass: class Shape { get color() { return this._color; } set color(c) { this._color = parseColorAsRGB(c); this.markChanged(); // canvas } }
static
properties: we have no syntactic way to change the function prototype during the definition (definition). Although this can be bypassed using Object.setPrototypeOf
, this approach is generally less fast and has less optimization options for JS engines than when we have the opportunity to set a function prototype when it is created. class Circle { // . } // Object.setPrototypeOf(Circle.prototype, Shape.prototype); // Object.setPrototypeOf(Circle, Shape);
extends
so we can write like: class Circle extends Shape { // . }
extends
, as long as it has a valid constructor with the prototype
property. For example, fit:Object.prototype
.Circle
subclass that handles (handles) the scaling of a circle by a given number. To achieve this, we can write a rather unnatural class: class ScalableCircle extends Circle { get radius() { return this.scalingFactor * super.radius; } set radius() { throw new Error("ScalableCircle radius is constant." + "Set scaling factor instead."); } // , scalingFactor }
radius
getter uses super.radius
. This new super
keyword allows us to search for a property starting from the prototype, ignoring any shadowing we may have.super[expr]
, by the way, also works) can be used in any function that is declared using the definition syntax (definition) of methods. Although these functions can be pulled out of the original object, the accesses are tied to the object where the method was defined (defined) for the first time. This means that by “pulling out” a method into a local variable (oh, this Javascript - approx. Transl. ), We will not change the behavior of super-access. var obj = { toString() { return "MyObject: " + super.toString(); } } obj.toString(); // MyObject: [object Object] var a = obj.toString; a(); // MyObject: [object Object]
Source: https://habr.com/ru/post/264813/
All Articles