Heim  >  Artikel  >  Web-Frontend  >  Ist es6-Klasse syntaktischer Zucker?

Ist es6-Klasse syntaktischer Zucker?

青灯夜游
青灯夜游Original
2022-10-17 18:03:101822Durchsuche

Klasse ist syntaktischer Zucker. Grund: Die Klasse basiert auf der Implementierung der Prototypenvererbung, die keinen Einfluss auf die Funktion der Sprache hat. Sie erleichtert lediglich das Schreiben und Lesen der Grammatik, was das Schreiben von Objektprototypen klarer und einfacher machen kann eher wie die Grammatik der objektorientierten Programmierung.

Ist es6-Klasse syntaktischer Zucker?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, ECMAScript Version 6, Dell G3-Computer.

ES6-Klasse class - syntaktischer Zucker

class (Klasse) wird als Vorlage für Objekte eingeführt, und Klassen können über das Schlüsselwort class definiert werden. Sein Wesen ist eine Funktion, die als syntaktischer Zucker betrachtet werden kann, wodurch die Schreibmethode des Objektprototyps klarer wird und der Syntax der objektorientierten Programmierung ähnlicher wird.

Seine Klasse unterscheidet sich von anderen Sprachen. Sie basiert immer noch auf der Implementierung der prototypischen Vererbung, die keinen Einfluss auf die Funktion der Sprache hat. Sie erleichtert lediglich das Schreiben und Lesen.

Warum heißt es, ES6-Klassen? sind syntaktischer Zucker. der Klasse?

    1. Prototypenbasiertes OOP
  • Schauen wir uns zunächst ein Prototypenbeispiel an:
  • function Person (name, sex) {
    	this.name = name
    	this.sex = sex
    }
     
    function Man (name) {
    	this.name = name
    }
     
    Man.prototype = new Person('', 'male')
     
    let Jy = new Man('Jy')
     
    console.log(Jy.name, Jy.sex) // Jy, male
  • Dies ist ein sehr einfaches Beispiel dafür, wie wir Prototypen verwenden. Eine Person hat einen Namen und ein Geschlecht . Person, Jy ist ein Mann. Erinnern wir uns zunächst an dieses Beispiel und schreiben wir dieses Beispiel mithilfe der folgenden Klasse um.

Tipps: Neu, Dies usw. wurden von Brendan Eich hinzugefügt, um es dem OOP von Java ähnlicher zu machen. Interessierte Leser können die relevanten Informationen selbst überprüfen.

2. OOP der ES6-Klasse

class Person {
	constructor (name, sex) {
		this.name = name
		this.sex = sex
	}
}
 
class Man extends Person {
	constructor (name) {
		super('', 'male')
		this.name = name
	}
}
 
let Jy = new Man('Jy')
 
console.log(Jy.name, Jy.sex) // Jy, 'male'
Indem wir dieses Beispiel umschreiben, sprechen wir darüber, was mit ihnen in der ES6-Spezifikation gemacht wird.

3. Klasse OOP, implementiert mit Prototype (ES6-Spezifikation) Vor ES6 waren JS-Objekte tatsächlich Sammlungen von Attributen, und Attribute waren eine Reihe von Schlüssel-Wert-Paaren (Schlüssel, Wert). Zeichenfolge oder Symbol, der Wert umfasst den charakteristischen Wert des Datenattributs und den charakteristischen Wert des Zugriffselements.

Sie sagten, dass gewöhnliche Attribute in Ordnung seien, aber gibt es keine Methoden unter Objekten? Wie ist daraus eine Sammlung von Attributen geworden?

Tatsächlich lautet die Definition der Methode in der ES5-Spezifikation „Funktion, die der Wert einer Eigenschaft ist“, die nur ein Funktionsattribut des Objekts ist und nicht als Methode bezeichnet werden kann. Dies geschah erst in ES6 Methodendefinitionen wurden in die Spezifikation aufgenommen. Wir können uns Dinge im Zusammenhang mit OOP in ES3 vorstellen: Prototyp, Neu, Dies, Konstruktor, Instanz von, nicht einmal die Standardeigenschaft .

Glücklicherweise haben wir in ES5 viele Methoden hinzugefügt, um es zu vervollständigen und zu vervollständigen:

Object.defineProperty

Object.freeze

Object.create__proto__

Object.getPrototypeOf

Object.setPrototypeOf
  • isPrototypeOf
  • ...
  • Schauen wir uns noch einmal einen Code an:
  • let obj = {
    	name: 'Jy',
    	speak () { // Note: it's not speak: function () {}
    		console.log(this.name, super.name)
    	}
    }
     
    obj.speak() // Jy, undefined
     
    Object.setPrototypeOf(obj,  { name: 'super' })
     
    obj.speak() // Jy, super
     
    let speak = obj.speak
    speak() // undefined, super
  • obj.speak ist in ES6 als Methode definiert, es hat das Attribut [[homeObject]], homeObject zeigt auf das Objekt, auf dem die Methode aufgerufen wird ( Code Der Mittelfinger ist obj), bei dem es sich um interne Slots handelt, die an das Objekt gebunden sind, das heißt, Sie können es nicht ändern, was einer Festcodierung entspricht.
  • Was nützt homeObject also? Es ist eng mit super verwandt. Wenn das Schlüsselwort super analysiert wird, wird der Prototyp von homeObject gefunden.
  • Einfach ausgedrückt kann es wie folgt zusammengefasst werden:
let homeObj = Method[[HomeObject]] = obj

super = Object.getPrototypeOf(homeObj)

Hinweis: homeObject ist statisch an gebunden intern in Slots, während super dynamisch durchsucht wird.

    Nachdem wir über Super gesprochen haben, sprechen wir über Extends und Konstruktoren.
  • Wenn die übergeordnete Klasse null ist, führen Sie Object.setPrototypeOf(C.prototype, null) aus.
Der Unterschied zwischen dem ersten und zweiten Teil des obigen Codes besteht darin, ob der Konstruktor explizit deklariert ist, ebenso wie diese beiden Codeteile Äquivalent? Die Antwort ist gleichwertig.

So ist es in der Spezifikation definiert:

Der dritte Teil des Codes erbt null. Es wird kein Syntaxfehler gemeldet, aber wir können kein neues C erstellen. Der Grund dafür ist, dass der Konstruktor von null aufgerufen wird wenn neu, null-Konstruktor jedoch nicht.

Sehen Sie hier: Die Klassen-Oop- und Spezifikationsdeklarationen von ES6 verwenden alle Prototypen für den Betrieb. Können wir also sagen, dass die Klasse der Syntaxzucker von Prototypen ist?

  • 4. Babel-kompilierte Klasse
In tatsächlichen Projekten verwenden wir Babel hauptsächlich zum Kompilieren von ES6- und 7-Codes. Daher werden wir in diesem Abschnitt den folgenden Babel-kompilierten Code analysieren, bei dem einige Fehlerberichte weggelassen werden Etwas verwandter Code zur Typerkennung, um das Thema der Verwendung von Prototypen zur Implementierung von OOP besser darzustellen.

Vor dem Kompilieren:

class A extends B { }
 
class A extends B {
	constructor (...args) {
		super(args)
	}
}
 
class C extends null { }
Nach dem Kompilieren:

"use strict";
 
function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  };
  return _getPrototypeOf(o);
}
 
function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      writable: true,
      configurable: true
    }
  });
  if (superClass) _setPrototypeOf(subClass, superClass);
}
 
function _setPrototypeOf(o, p) {
  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
    o.__proto__ = p;
    return o;
  };
  return _setPrototypeOf(o, p);
}
 
var A =
  /*#__PURE__*/
  function (_B) {
    _inherits(A, _B);
 
    function A() {
 
      return _getPrototypeOf(A).apply(this, arguments);
    }
 
    return A;
  }(B);
 
console.log(new A());

我们重点看_inherits 方法,跟我们上述说的extends做的两件事是一样的:

  • Object.setPrototypeOf(subClass, superClass)
  • Object.setPrototypeOf(subClass.prototype, superClass.prototype)

只不过它采用的是Object.create方法,这两个方法的区别可以去MDN上查看。

再看function A内部,其实就是执行了B的构造器函数来达到super(arguments)的效果, 这个与规范:如果没有显示声明constructor会自动加上constructor是一致的。

5. 总结

至此,我们终于理解了为什么class是原型的语法糖以及如何使用原型来实现class这一语法糖。

但切记我们使用原型的目的并不是来模拟class oop的,prototype based的oop应该用prototype去理解而不是class。

ES6的class oop 是不完备的 ,例如abstract class 、interface、private等都还没有,不过有些功能已经在提案中了,大家可以拥抱它,或者TypeScript是个不错的选择,如果你的项目中使用到了TS, 欢迎你到评论区分享你的感受。

【相关推荐:javascript视频教程编程视频

Das obige ist der detaillierte Inhalt vonIst es6-Klasse syntaktischer Zucker?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn