ECMAScript 6 Class
2018-02-28
ECMAScript 6 CLASSES
Class in ECMAScript 5
1 | function PersonType(name){ |
Class Declarations in ECMAScript 6
A Basic Class Declaration
1 | class PersonClass { |
- Class declarations are not hoisted, like
let
declarations, so they exist in the termporal dead zone until exectution reaches the declaration - All code inside the class declarations runs in strict mode automatically
- All methods are nonenumerable
- When lacking the
constructor
methods, it will throws an error - Calling the class constructor without
new
throws an error - Class method use the concise syntax. Therefore, there’s no need to use
function
keyword - Own properties can be created inside a class constructor (recomannded) or method.
- Class prototypes are read-only
1 | // equivalent of PersonClass |
Class Expressions
Anonymous Class Expression
1 | let PersonClass = class { |
- Class expression are functionally equivalent to class declarations.
- Expect that the anonymous class expression has an empty name property.
Named Class Expression
1 |
|
- The PersonClass2 identifier exists only within the class definition so it can be used inside class methods
-As following code shows the different:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21let PersonClass = (function(){
;
const PersonClass2 = function(name){
if(typeof new.target === "undefined"){
throw new Error("Constructor must be called with new.")
}
this.name = name;
}
Object.defineProperty(PersonClass2.prototype, "sayName", {
value: function(){
if(typeof new.target !== "undefined"){
throw new Error("Method cannot be called with new");
}
console.log(this.name);
},
enumerable: false,
writable: true,
configurable: true
});
return PersonClass2;
}())
Accessor Properties
- Classes allow you to define accessor properties on the prototype
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class CustomHTMLElement {
constructor(element) {
this.element = element;
}
get html() {
return this.element.innerHTML;
}
set html(value) {
this.element.innerHTML = value;
}
}
var descriptor = Object.getOwnPropertyDescriptor(CustomHTMLElement.prototype, "html");
console.log("get" in descriptor); //true
console.log("set" in descriptor); // true
console.log(descriptor.enumerable); //false
1 | // equivalent no-class version |
Computed Member Names
- Glass Methods and accessor properties can also have computed names, which using square brackets around an expression and has the same syntax you use for object literal computed names.
1 | let methodName = 'sayName'; |
Generator Methods
1 | class MyClass { |
- Generator are more useful for a collection of values. You can define the default iterator for a class by using
Symbol.iterator
to define a generator method:
1 | class Collection { |
Static Members
- Static members in ECMAScript 5
1 | function PersonType(name){ |
ECMAScript 6 use the formal
static
annotation before method or accessor property name.1
2
3
4
5
6
7
8
9
10
11
12
13
class PersonClass {
constructor(name){
this.name = name;
}
sayName(){
console.log(this.name);
}
static create(name){
return new PersonClass(name);
}
}
let person = PersonClass.create("Nick");static
can’t be used with theconsturctor
method definition
Inheritance with Derived Classes
- The Inheritance pior to ECMAScript 6
1 | function Rectangle(length, width){ |
- Classes make inheritance easier to implement by using the
extends
keyword to specify the function from which the class should inherit. - The prototypes are automatically adjusted, and you can access the base class constructor by calling the
super()
method .
1 | class Rectangle { |
- the
Square
class inherits fromRectangle
using theextends
keyword. TheSquare
constructor usessuper()
to call theRectangle
constructor with the specified arguments. - Classes that inherit from the other classes are referred as derived classes, which require you to use
super()
if you specify a constructor. - If you choose not to use a constructor,
super()
is automatically called fro you with arguments upon creating a new instance of the class - not use
super()
in a nonderived class - class
super()
before accessingthis
in the constructor.super()
is responsible for initializingthis
.
1 | class Square extends Rectangle { |
Shadowing Class Methods
- The methods on derived classes always shadow methods of the same name on the base class
- call the base class version of the method by using the
super.getArea()
method
Inherited Static Members
1 | class Rectangle { |
Dervied Classes from Expressions
- You can use
extends
with any expression as long as the expression resolves to a function with[[Construct]]
and a prototype. - It’s possible to create different inheritance approaches.
1 | let SerializableMixin = { |
- you can use any expression after
extends
, but not all expressions result in a valid class. Specifically, usingnull
or a generator function will cause errors. because there is no[[Construct]]
to call
Inheriting from Built-Ins
Custmoized Array in ECMAScript 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// built - in array behavior
var colors = [];
colors[0] = 'red';
console.log(colors.length); //1
colors.length = 0;
console.log(colors[0]);
// trying to inheirt from array in ES5
function MyArray(){
Array.apply(this, arguments);
}
MyArray.prototype = Object.create(Array.prototype, {
constructor: {
value: MyArray,
writable: true,
configurable: true,
enumerable: true
}
});
var colors = new MyArray();
colors[0] = "red";
console.log(colors.length); //0
colors.length = 0;
console.log(colors[0]); //"red"The
length
and numeric properties on an instance ofMyArray
don’t behave the same way they do for the built-in array- the value of
this
is first created by the derived type and then the base type constructor is called, which measthis
start out as an instance ofMyArray
and then is decorated with additional properties fromArray
1 | class MyArray extends Array { |
- In ECMAScript 6, the value of
this
is first created by the base and then modified by the dervied class constructor. The result is thatthis
starts with all the built-in functionality of the base.
The Symbol.species
Property
- A convenient aspect of inheriting from built-ins is that any method that returns an instance of the built-in will automatically return a derived class instance instead.
1 | class MyArray extends Array { |
- Behind the scenes, the
Symbol.species
property is actually making this change. - The
Symbol.species
well-known symbol is used to define a static accessor property that returns a function. - That function is a constructor to use whenever an instance of the class must be created inside an instance method, instead of using the constructor.
1 | // implement on a custom class |
- Any call to
this.constructor[Symbol.species]
returnsMyClass
.
1 |
|
Using new.target in Class Constructors
new.target
‘s value changes depending on how a function is called.- the
new.target
is always defined inside class constructors. But the value may not always be the same
1 | class Rectangle { |
- Square is calling the
Rectangle
constructor, sonew.target
is equal toSquare
when the Rectange constructor is called. - This gives each constructor the ability to alter its behavior based on how it’s being called.
1 | // abstract base class |