Κοινή χρήση τεχνολογίας

Περίληψη τάξης ES6 (9)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Η κλάση στο ES6 είναι μια συντακτική ζάχαρη για αντικειμενοστραφή προγραμματισμό, παρέχοντας έναν συνοπτικό τρόπο ορισμού της δομής και της συμπεριφοράς των αντικειμένων.

Στη γλώσσα JavaScript, ο παραδοσιακός τρόπος δημιουργίας αντικειμένων παρουσίας είναι μέσω κατασκευαστών. Παρακάτω είναι ένα παράδειγμα.

function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Βασικά, η κλάση ES6 μπορεί να θεωρηθεί απλώς μια συντακτική ζάχαρη. Οι περισσότερες από τις λειτουργίες της μπορούν να επιτευχθούν με το ES5. Ο παραπάνω κώδικας ξαναγράφεται χρησιμοποιώντας κλάσεις ES6, ως εξής:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Οι κλάσεις ES6 μπορούν να θεωρηθούν ως ένας άλλος τρόπος γραφής κατασκευαστών:

class Point {
  // ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true

----------------------------------------------------------------------------
class Point {
  constructor() {
    // ...
  }
  toString() {
    // ...
  }
  toValue() {
    // ...
  }
}
// 等同于
Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

Κύρια χαρακτηριστικά:

1. Δηλωτική σύνταξη: Χρησιμοποιήστε τη λέξη-κλειδί class για να δηλώσετε μια κλάση.
2. Κατασκευαστής: Χρησιμοποιήστε τη μέθοδο κατασκευής για να αρχικοποιήσετε μια παρουσία κλάσης.
3. Μέθοδοι παραδείγματος: Μια κοινή μέθοδος που ορίζεται μέσα σε μια κλάση, χρησιμοποιήστε αυτήν για πρόσβαση στις ιδιότητες του στιγμιότυπου.
4. Στατικές μέθοδοι: Ορίζεται χρησιμοποιώντας τη στατική λέξη-κλειδί και δεν εξαρτάται από την παρουσία της κλάσης.
5. Ιδιότητες παραδείγματος: Εκκίνηση στον κατασκευαστή ή χρησιμοποιήστε τη σύνταξη δήλωσης πεδίου (προς το παρόν είναι μια πρόταση Στάδιο 3).
6. Κληρονομικότητα: Υλοποιήθηκε χρησιμοποιώντας τη λέξη-κλειδί επέκτασης.
7. σούπερ λέξη-κλειδί: Καλέστε τον κατασκευαστή ή τη μέθοδο της γονικής κλάσης στον κατασκευαστή της υποκλάσης.
8. λήπτης και ρυθμιστής: Χρησιμοποιήστε το get and set για να ορίσετε πρόσθετα για ιδιότητες.
9. Ιδιωτικές ιδιότητες και μέθοδοι: Χρησιμοποιήστε το # για να ορίσετε ιδιωτικές ιδιότητες και μεθόδους (προς το παρόν αποτελεί πρόταση για το Στάδιο 3).

1. Βασικός ορισμός κλάσης και στιγμιότυπο

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return `Point(${this.x}, ${this.y})`;
    }
}

let point = new Point(10, 20);
console.log(point.toString()); // 输出: Point(10, 20)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2. Στατικές μέθοδοι και ιδιότητες

class MathUtils {
	constructor() {
    	console.log(MyClass.myStaticProp); // 42
    }
    static add(a, b) {
        return a + b;
    }
    static myStaticProp = 42;
}

console.log(MathUtils.add(1, 2)); // 输出: 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3. Κληρονομικό και υπερ

class Rectangle {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }

    area() {
        return this.width * this.height;
    }
}

class Square extends Rectangle {
    constructor(sideLength) {
        super(sideLength, sideLength);
    }
}

let square = new Square(5);
console.log(square.area()); // 输出: 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

4. λήπτης και ρυθμιστής

class Rectangle {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }

    get area() {
        return this.width * this.height;
    }

    set width(newWidth) {
        if (newWidth > 0) {
            this.width = newWidth;
        } else {
            console.log("Width must be positive.");
        }
    }
}

let rect = new Rectangle(4, 5);
console.log(rect.area); // 输出: 20
rect.width = -10; // 输出: Width must be positive.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Σημειώσεις για τα μαθήματα

(1) Αυστηρή λειτουργία

Εσωτερικά, οι κλάσεις και οι μονάδες βρίσκονται σε αυστηρή λειτουργία από προεπιλογή, επομένως δεν χρειάζεται να χρησιμοποιήσετε τη χρήση αυστηρής για να καθορίσετε τη λειτουργία εκτέλεσης. Εφόσον ο κώδικάς σας είναι γραμμένος σε μια τάξη ή λειτουργική μονάδα, είναι διαθέσιμη μόνο η αυστηρή λειτουργία. Λαμβάνοντας υπόψη ότι όλος ο μελλοντικός κώδικας θα εκτελείται πραγματικά σε ενότητες, το ES6 αναβαθμίζει στην πραγματικότητα ολόκληρη τη γλώσσα σε αυστηρή λειτουργία.

(2) Δεν υπάρχει προώθηση

Οι τάξεις δεν έχουν μεταβλητή ανύψωση (ανυψωτικό), που είναι εντελώς διαφορετικό από το ES5.

new Foo(); // ReferenceError
class Foo {}

//不会报错
//因为 Bar 继承 Foo 的时候, Foo 已经有定义了。
//但是,如果存在 class 的提升,上面代码就会报错,
//因为 class 会被提升到代码头部,而 let 命令是不提升的,
//所以导致 Bar 继承 Foo 的时候, Foo 还没有定义。
{
  let Foo = class {};
  class Bar extends Foo {
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

(3) χαρακτηριστικό όνομα

Εφόσον στην ουσία, μια κλάση ES6 είναι απλώς ένα περιτύλιγμα για τον κατασκευαστή ES5, πολλά χαρακτηριστικά της συνάρτησης κληρονομούνται από την Κλάση, συμπεριλαμβανομένου του χαρακτηριστικού name.

class Point {}
Point.name // "Point"
//name 属性总是返回紧跟在 class 关键字后面的类名。
  • 1
  • 2
  • 3

(4)Μέθοδος γεννήτριας

Εάν πριν από μια μέθοδο υπάρχει ένας αστερίσκος (*), σημαίνει ότι η μέθοδος είναι συνάρτηση Generator.

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

//Foo 类的 Symbol.iterator 方法前有一个星号,表示该方法是一个 Generator 函数。 
//Symbol.iterator 方法返回一个 Foo 类的默认遍历器, for...of 循环会自动调用这个遍历器。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

(5) Το θέμα αυτού

Εάν μια μέθοδος κλάσης περιέχει αυτό, δείχνει σε μια παρουσία της κλάσης από προεπιλογή. Ωστόσο, πρέπει να είστε πολύ προσεκτικοί, καθώς αυτή η μέθοδος μπορεί να προκαλέσει σφάλματα εάν χρησιμοποιηθεί μόνη της.

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Αποφύγετε να το χρησιμοποιήσετε, συνδέστε το στον κατασκευαστή:

class Logger {
  constructor() {
    this.printName = this.printName.bind(this);
  }
  // ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Αποφύγετε τη χρήση αυτού, χρησιμοποιήστε τις λειτουργίες βέλους:

class Obj {
  constructor() {
    this.getThis = () => this;
  }
}
const myObj = new Obj();
myObj.getThis() === myObj // true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Αποφύγετε να το χρησιμοποιήσετε, χρησιμοποιήστε Proxy

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());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18