Classesare a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are unique to classes.
Like function expressions, class expressions may be anonymous, or have a name that's different from the variable that it's assigned to. However, unlike function declarations, class declarations have the same temporal dead zone restrictions as let or const and behave as if they are not hoisted.
Methods are defined on the prototype of each class instance and are shared by all instances. Methods can be plain functions, async functions, generator functions, or async generator functions. For more information, see method definitions.
The static keyword defines a static method or field for a class. Static properties (fields and methods) are defined on the class itself instead of each instance. Static methods are often used to create utility functions for an application, whereas static fields are useful for caches, fixed-configuration, or any other data that doesn't need to be replicated across instances.
Class fields are similar to object properties, not variables, so we don't use keywords such as const to declare them. In JavaScript, private properties use a special identifier syntax, so modifier keywords like public and private should not be used either.
As seen above, the fields can be declared with or without a default value. Fields without default values default to undefined. By declaring fields up-front, class definitions become more self-documenting, and the fields are always present, which help with optimizations.
It's an error to reference private fields from outside of the class; they can only be read or written within the class body. By defining things that are not visible outside of the class, you ensure that your classes' users can't depend on internals, which may change from version to version.
When a static or instance method is called without a value for this, such as by assigning the method to a variable and then calling it, the this value will be undefined inside the method. This behavior is the same even if the "use strict" directive isn't present, because code within the class body is always executed in strict mode.
\n It's an error to reference private fields from outside of the class; they can only be read or written within the class body.\n By defining things that are not visible outside of the class, you ensure that your classes' users can't depend on internals, which may change from version to version.\n
When a static or instance method is called without a value for this, such as by assigning the method to a variable and then calling it, the this value will be undefined inside the method. This behavior is the same even if the \"use strict\" directive isn't present, because code within the class body is always executed in strict mode.
Classes provide a means of bundling data and functionality together. Creatinga new class creates a new type of object, allowing new instances of thattype to be made. Each class instance can have attributes attached to it formaintaining its state. Class instances can also have methods (defined by itsclass) for modifying its state.
(Lacking universally accepted terminology to talk about classes, I will makeoccasional use of Smalltalk and C++ terms. I would use Modula-3 terms, sinceits object-oriented semantics are closer to those of Python than C++, but Iexpect that few readers have heard of it.)
Attributes may be read-only or writable. In the latter case, assignment toattributes is possible. Module attributes are writable: you can writemodname.the_answer = 42. Writable attributes may also be deleted with thedel statement. For example, del modname.the_answer will removethe attribute the_answer from the object named by modname.
Namespaces are created at different moments and have different lifetimes. Thenamespace containing the built-in names is created when the Python interpreterstarts up, and is never deleted. The global namespace for a module is createdwhen the module definition is read in; normally, module namespaces also lastuntil the interpreter quits. The statements executed by the top-levelinvocation of the interpreter, either read from a script file or interactively,are considered part of a module called __main__, so they have their ownglobal namespace. (The built-in names actually also live in a module; this iscalled builtins.)
The local namespace for a function is created when the function is called, anddeleted when the function returns or raises an exception that is not handledwithin the function. (Actually, forgetting would be a better way to describewhat actually happens.) Of course, recursive invocations each have their ownlocal namespace.
The global statement can be used to indicate that particularvariables live in the global scope and should be rebound there; thenonlocal statement indicates that particular variables live inan enclosing scope and should be rebound there.
Class definitions, like function definitions (def statements) must beexecuted before they have any effect. (You could conceivably place a classdefinition in a branch of an if statement, or inside a function.)
then MyClass.i and MyClass.f are valid attribute references, returningan integer and a function object, respectively. Class attributes can also beassigned to, so you can change the value of MyClass.i by assignment.__doc__ is also a valid attribute, returning the docstring belonging tothe class: "A simple example class".
In the MyClass example, this will return the string 'hello world'.However, it is not necessary to call a method right away: x.f is a methodobject, and can be stored away and called at a later time. For example:
As discussed in A Word About Names and Objects, shared data can have possibly surprisingeffects with involving mutable objects such as lists and dictionaries.For example, the tricks list in the following code should not be used as aclass variable because just a single list would be shared by all Doginstances:
There is no shorthand for referencing data attributes (or other methods!) fromwithin methods. I find that this actually increases the readability of methods:there is no chance of confusing local variables and instance variables whenglancing through a method.
Often, the first argument of a method is called self. This is nothing morethan a convention: the name self has absolutely no special meaning toPython. Note, however, that by not following the convention your code may beless readable to other Python programmers, and it is also conceivable that aclass browser program might be written that relies upon such a convention.
Any function object that is a class attribute defines a method for instances ofthat class. It is not necessary that the function definition is textuallyenclosed in the class definition: assigning a function object to a localvariable in the class is also ok. For example:
The name BaseClassName must be defined in anamespace accessible from the scope containing thederived class definition. In place of a base class name, other arbitraryexpressions are also allowed. This can be useful, for example, when the baseclass is defined in another module:
Execution of a derived class definition proceeds the same as for a base class.When the class object is constructed, the base class is remembered. This isused for resolving attribute references: if a requested attribute is not foundin the class, the search proceeds to look in the base class. This rule isapplied recursively if the base class itself is derived from some other class.
Derived classes may override methods of their base classes. Because methodshave no special privileges when calling other methods of the same object, amethod of a base class that calls another method defined in the same base classmay end up calling a method of a derived class that overrides it. (For C++programmers: all methods in Python are effectively virtual.)
An overriding method in a derived class may in fact want to extend rather thansimply replace the base class method of the same name. There is a simple way tocall the base class method directly: just call BaseClassName.methodname(self,arguments). This is occasionally useful to clients as well. (Note that thisonly works if the base class is accessible as BaseClassName in the globalscope.)
3a8082e126