The ES6 class
can be seen as just a syntactic sugar, most of its functions, ES5 can be done, the new class
wording just let the object prototype written more clearly, like object-oriented programming syntax only.
//定义类
class Point {
constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
The above code defines a "class", there can be seen a constructor
method, which is the constructor, the this
keyword represents the object instance.
Point
In addition to the class constructor it is also defined a toString
method. Note that the definition method "class" when in front of does not need to add function
this keyword, go directly to the function definition into it. Further, the method does not require between commas, plus error.
The data type is the class of functions, the class itself points to the constructor.
When in use, direct use of the class new
command
class Bar {
doStuff() {
console.log('stuff'); } } var b = new Bar(); b.doStuff() // "stuff"
All methods defined in the class are the class prototype
attributes above
class Point {
constructor(){
// ... } toString(){ // ... } toValue(){ // ... } } // 等同于 Point.prototype = { toString(){}, toValue(){} };
In the instance of the class call the method above, is actually a method call on a prototype.
class B {}
let b = new B(); b.constructor === B.prototype.constructor // true
The above code, b
is an instance of class B, it constructor
is to Type B prototype constructor
method.
Further, all methods defined within the class, are not enumerated (non-enumerable).
class Point {
constructor(x, y) {
// ... } toString() { // ... } } Object.keys(Point.prototype) // [] Object.getOwnPropertyNames(Point.prototype) // ["constructor","toString"]
constructor method
constructor
Is the default class method, by new
generating a command object instance, the method is automatically invoked. There must be a class constructor
method, if no explicit definition, an empty constructor
method will be added by default.
constructor() {}
Class constructor, do not use new
is not called, it will complain. This is a major difference with the general constructor of it, who do not new
can be performed.
class Foo {
constructor() {
return Object.create(null); } } Foo() // TypeError: Class constructor Foo cannot be invoked without 'new'
Examples of object classes
Written instance of an object class is generated, and ES5 exactly the same, but also use new
command. If you forget to add new
, like that call functions Class
, it will be thrown.
There is no variable lift
Class does not exist variable lift (hoist), this is completely different and ES5.
new Foo(); // ReferenceError
class Foo {}
Class Expression
Like functions, classes may be defined in the form using the expression
const MyClass = class Me {
getClassName() {
return Me.name; } };
The above code uses expression defines a class. Note that the name of this class is MyClass
and not Me
, Me
available only in the internal code of the Class, refer to the current class.
let inst = new MyClass();
inst.getClassName() // Me
Me.name // ReferenceError: Me is not defined
The above codes indicate Me
only within Class is defined.
If the unused inner class, it can be omitted Me
, i.e. can be written in the following form.
const MyClass = class { /* ... */ };
The use of Class expressions can write Class immediate execution.
let person = new class {
constructor(name) { this.name = name; } sayName() { console.log(this.name); } }('张三'); person.sayName(); // "张三"
The above code, person
is an example of a class executed immediately.
Private methods
One method is a private method out of the module, because all methods of internal modules are visible outside
class Widget {
foo (baz) {
bar.call(this, baz);
}
// ... } function bar(baz) { return this.snaf = baz; }
The above code, foo
is a public method, internal calls bar.call(this, baz)
. This makes it bar
actually became a private methods of the current module.
Another way is to use Symbol
the uniqueness of values, the name of the private methods named as a Symbol
value.
const bar = Symbol('bar');
const snaf = Symbol('snaf'); export default class myClass{ // 公有方法 foo(baz) { this[bar](baz); } // 私有方法 [bar](baz) { return this[snaf] = baz; } // ... };
The above code, bar
and snaf
all Symbol
values, leading to a third party can not get to them, thus achieving the effect of private methods and private property.
this point
If the class containing internal method this
, it points to the default instance of the class. However, be very careful, once using this method alone, it is likely an error.
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`); } print(text) { console.log(text); } } const logger = new Logger(); const { printName } = logger; printName(); // TypeError: Cannot read property 'print' of undefined
The above code, the printName
method this
, points to the default Logger
instance of the class. However, if you use this method to extract alone, this
it will point to the environment in which the process is running, because there is no print
method results in an error.
A simpler solution is to bind in the constructor this
, so you can not miss print
way to go.
class Logger {
constructor() {
this.printName = this.printName.bind(this); } // ... }
Another solution is to use a function of the arrows.
class Logger {
constructor() {
this.printName = (name = 'there') => { this.print(`Hello ${name}`); }; } // ... }
Another solution is to use Proxy
, when the acquisition method, automatically bound this
.
function selfish (target) {
const cache = new WeakMap(); const handler = { get (target, key) { const value = Reflect.get(target, key); if (typeof value !== 'function') { return value; } if (!cache.has(value)) { cache.set(value, value.bind(target)); } return cache.get(value); } }; const proxy = new Proxy(target, handler); return proxy; } const logger = selfish(new Logger());
Strict Mode
Inner classes and modules, the default mode is strict, it is not necessary to use use strict
a specified mode of operation. As long as you write code in class or module in, only strict mode is available.
The name attribute
class Point {}
Point.name // "Point"
name
Property always returns immediately class
after the class name keywords.
Class inheritance
By between Class extends
inheritance keyword
class ColorPoint extends Point {}
The above code defines a ColorPoint
class, by extends
keywords, inherits Point
all the attributes and methods of the class. But without deploying any code, so these two classes exactly the same, equal to a copy of the Point
class. Below, we in ColorPoint
the interior plus the code.
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // 调用父类的constructor(x, y) this.color = color; } toString() { return this.color + ' ' + super.toString(); // 调用父类的toString() } }
The above code, constructor
the method and toString
in the method, have emerged super
keyword, where it shows the structure of the parent class for the new parent class this
object.
Subclass must constructor
call the method super
method, otherwise it will error when creating a new instance. This is because the subclass does not own this
the object, but inherit the parent class this
object, then its processing. If you do not call the super
method, the subclass would not this
object.
class Point { /* ... */ }
class ColorPoint extends Point { constructor() { } } let cp = new ColorPoint(); // ReferenceError
The above code, ColorPoint
inherited from a parent class Point
, but it does not call the constructor super
method, resulting in an error when creating a new instance.
Another point to note is that in the constructor of the subclass, only the call super
only after you can use this
keywords, otherwise it will error. This is because the construction of a subclass instance, is based on the parent process instance, only super
method to return the parent class instance.
class Point {
constructor(x, y) {
this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y, color) { this.color = color; // ReferenceError super(x, y); this.color = color; // 正确 } }
The above code, the subclass constructor
method is not called super
before, on the use of this
keywords, the result of an error, and on the super
following approach is correct.
Class function values (getters) and stored-value functions (the setter)
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter'; } set prop(value) { console.log('setter: '+value); } } let inst = new MyClass(); inst.prop = 123; // setter: 123 inst.prop // 'getter'
In the above code, prop
the attribute has a corresponding function value stored-value functions, and therefore the assignment and reading behavior is customized.
Class of Generator method
If the previous method plus an asterisk ( *
), it means that the method is a Generator function.
class Foo {
constructor(...args) {
this.args = args; } * [Symbol.iterator]() { for (let arg of this.args) { yield arg; } } } for (let x of new Foo('hello', 'world')) { console.log(x); } // hello // world
The above code, Foo
like Symbol.iterator
the former method has an asterisk indicates that the method is a function Generator. Symbol.iterator
Method returns a Foo
default walker class, for...of
the cycle will automatically call this walker.
Class of static methods
If the previous method, add static
keywords, it means that the method can not be inherited instance, but directly through the class to call, which is called "static method."
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function
The above code, Foo
the class of classMethod
the former method has static
keywords, that the method is a static method, may be directly Foo
invoked on a class ( Foo.classMethod()
), instead of Foo
calling the instances of the class. If you call the static method on an instance, it will throw an error, indicating that the method does not exist.
Static methods of the parent class can be inherited by subclasses.
class Foo {
static classMethod() {
return 'hello'; } } class Bar extends Foo { } Bar.classMethod(); // 'hello'
In the above code, the parent class Foo
has a static method, a subclass Bar
can call this method.
Static methods are also possible from super
calling on the object.
class Foo {
static classMethod() {
return 'hello'; } } class Bar extends Foo { static classMethod() { return super.classMethod() + ', too'; } } Bar.classMethod();
Class static and instance properties
Static Class attribute refers to the attribute itself, i.e. Class.propname
, rather than in an instance object ( this
Attribute I) a.
class Foo {
}
Foo.prop = 1;
Foo.prop // 1
The above wording of Foo
class defines a static properties prop
.
Currently, only such an approach is feasible because ES6 clear that internal Class only static methods, no static properties.
// 以下两种写法都无效
class Foo {
// 写法一
prop: 2
// 写法二 static prop: 2 } Foo.prop // undefined
ES7 there is a static property of the proposal , the current Babel transcoder support.
..........
Mixin mode of realization
...............
Original: http: //jsrun.net/tutorial/SZKKp