Class (class) and inheritance

The ES6 classcan be seen as just a syntactic sugar, most of its functions, ES5 can be done, the new classwording 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 constructormethod, which is the constructor, the thiskeyword represents the object instance.

PointIn addition to the class constructor it is also defined a toStringmethod. Note that the definition method "class" when in front of does not need to add functionthis 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 newcommand

class Bar {
  doStuff() {
    console.log('stuff'); } } var b = new Bar(); b.doStuff() // "stuff"

All methods defined in the class are the class prototypeattributes 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, bis an instance of class B, it constructoris to Type B prototype constructormethod.

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

constructorIs the default class method, by newgenerating a command object instance, the method is automatically invoked. There must be a class constructormethod, if no explicit definition, an empty constructormethod will be added by default.

constructor() {}

Class constructor, do not use newis not called, it will complain. This is a major difference with the general constructor of it, who do not newcan 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 newcommand. 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 MyClassand not Me, Meavailable 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 Meonly 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, personis 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, foois a public method, internal calls bar.call(this, baz). This makes it baractually became a private methods of the current module.

Another way is to use Symbolthe uniqueness of values, the name of the private methods named as a Symbolvalue.

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, barand snafall Symbolvalues, 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 printNamemethod this, points to the default Loggerinstance of the class. However, if you use this method to extract alone, thisit will point to the environment in which the process is running, because there is no printmethod results in an error.

A simpler solution is to bind in the constructor this, so you can not miss printway 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 stricta 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" 

nameProperty always returns immediately classafter the class name keywords.

Class inheritance

By between Class extendsinheritance keyword

class ColorPoint extends Point {}

The above code defines a ColorPointclass, by extendskeywords, inherits Pointall 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 Pointclass. Below, we in ColorPointthe 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, constructorthe method and toStringin the method, have emerged superkeyword, where it shows the structure of the parent class for the new parent class thisobject.

Subclass must constructorcall the method supermethod, otherwise it will error when creating a new instance. This is because the subclass does not own thisthe object, but inherit the parent class thisobject, then its processing. If you do not call the supermethod, the subclass would not thisobject.

class Point { /* ... */ }

class ColorPoint extends Point { constructor() { } } let cp = new ColorPoint(); // ReferenceError

The above code, ColorPointinherited from a parent class Point, but it does not call the constructor supermethod, resulting in an error when creating a new instance.

Another point to note is that in the constructor of the subclass, only the call superonly after you can use thiskeywords, otherwise it will error. This is because the construction of a subclass instance, is based on the parent process instance, only supermethod 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 constructormethod is not called superbefore, on the use of thiskeywords, the result of an error, and on the superfollowing 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, propthe 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, Foolike Symbol.iteratorthe former method has an asterisk indicates that the method is a function Generator. Symbol.iteratorMethod returns a Foodefault walker class, for...ofthe cycle will automatically call this walker.

Class of static methods

If the previous method, add statickeywords, 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, Foothe class of classMethodthe former method has statickeywords, that the method is a static method, may be directly Fooinvoked on a class ( Foo.classMethod()), instead of Foocalling 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 Foohas a static method, a subclass Barcan call this method.

Static methods are also possible from supercalling 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 ( thisAttribute I) a.

class Foo {
}

Foo.prop = 1;
Foo.prop // 1

The above wording of Fooclass 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

Guess you like

Origin www.cnblogs.com/caozhuzi/p/10963737.html