Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des JavaScript-Konstruktors und des „neuen“ Operators

Detaillierte Erläuterung des JavaScript-Konstruktors und des „neuen“ Operators

coldplay.xixi
coldplay.xixinach vorne
2020-11-13 17:39:522532Durchsuche

JavascriptDie Spalte stellt den „neuen“ Operator vor.

Detaillierte Erläuterung des JavaScript-Konstruktors und des „neuen“ Operators

Konstruktor und Operator „neu“

Die reguläre {...}-Syntax ermöglicht das Erstellen eines Objekts. Wir müssen jedoch häufig viele ähnliche Objekte erstellen, z. B. mehrere Benutzer oder Menüelemente usw. {...} 语法允许创建一个对象。但是我们经常需要创建许多类似的对象,例如多个用户或菜单项等。

这可以使用构造函数和 "new" 操作符来实现。

构造函数

构造函数在技术上是常规函数。不过有两个约定:

  1. 它们的命名以大写字母开头。
  2. 它们只能由 "new" 操作符来执行。

例如:

function User(name) {  this.name = name;  this.isAdmin = false;
}let user = new User("Jack");

alert(user.name); // Jackalert(user.isAdmin); // false复制代码

当一个函数被使用 new 操作符执行时,它按照以下步骤:

  1. 一个新的空对象被创建并分配给 this
  2. 函数体执行。通常它会修改 this,为其添加新的属性。
  3. 返回 this 的值。

换句话说,new User(...) 做的就是类似的事情:

function User(name) {  // this = {};(隐式创建)

  // 添加属性到 this
  this.name = name;  this.isAdmin = false;  // return this;(隐式返回)}复制代码

所以 new User("Jack") 的结果是相同的对象:

let user = {  name: "Jack",  isAdmin: false};复制代码

现在,如果我们想创建其他用户,我们可以调用 new User("Ann")new User("Alice") 等。比每次都使用字面量创建要短得多,而且更易于阅读。

这是构造器的主要目的 —— 实现可重用的对象创建代码。

让我们再强调一遍 —— 从技术上讲,任何函数都可以用作构造器。即:任何函数都可以通过 new 来运行,它会执行上面的算法。“首字母大写”是一个共同的约定,以明确表示一个函数将被使用 new 来运行。

new function() { ... }

如果我们有许多行用于创建单个复杂对象的代码,我们可以将它们封装在构造函数中,像这样:

let user = new function() {  this.name = "John";  this.isAdmin = false;  // ……用于用户创建的其他代码
  // 也许是复杂的逻辑和语句
  // 局部变量等};复制代码

构造器不能被再次调用,因为它不保存在任何地方,只是被创建和调用。因此,这个技巧旨在封装构建单个对象的代码,而无需将来重用。

构造器模式测试:new.target

进阶内容:

本节涉及的语法内容很少使用,除非你想了解所有内容,否则你可以直接跳过该语法。

在一个函数内部,我们可以使用 new.target 属性来检查它是否被使用 new 进行调用了。

对于常规调用,它为空,对于使用 new 的调用,则等于该函数:

function User() {
  alert(new.target);
}// 不带 "new":User(); // undefined// 带 "new":new User(); // function User { ... }复制代码

它可以被用在函数内部,来判断该函数是被通过 new 调用的“构造器模式”,还是没被通过 new 调用的“常规模式”。

我们也可以让 new 调用和常规调用做相同的工作,像这样:

function User(name) {  if (!new.target) { // 如果你没有通过 new 运行我
    return new User(name); // ……我会给你添加 new
  }  this.name = name;
}let john = User("John"); // 将调用重定向到新用户alert(john.name); // John复制代码

这种方法有时被用在库中以使语法更加灵活。这样人们在调用函数时,无论是否使用了 new,程序都能工作。

不过,到处都使用它并不是一件好事,因为省略了 new 使得很难观察到代码中正在发生什么。而通过 new 我们都可以知道这创建了一个新对象。

构造器的 return

通常,构造器没有 return 语句。它们的任务是将所有必要的东西写入 this,并自动转换为结果。

但是,如果这有一个 return 语句,那么规则就简单了:

  • 如果 return 返回的是一个对象,则返回这个对象,而不是 this
  • 如果 return 返回的是一个原始类型,则忽略。

换句话说,带有对象的 return 返回该对象,在所有其他情况下返回 this

例如,这里 return 通过返回一个对象覆盖 this

function BigUser() {  this.name = "John";  return { name: "Godzilla" };  // <-- 返回这个对象}

alert( new BigUser().name );  // Godzilla,得到了那个对象复制代码

这里有一个 return 为空的例子(或者我们可以在它之后放置一个原始类型,没有什么影响):

function SmallUser() {  this.name = "John";  return; // <-- 返回 this}

alert( new SmallUser().name );  // John复制代码

通常构造器没有 return 语句。这里我们主要为了完整性而提及返回对象的特殊行为。

省略括号

顺便说一下,如果没有参数,我们可以省略 new

Dies kann mithilfe von Konstruktoren und dem Operator "new" erreicht werden.

Konstruktor

Konstruktoren sind technisch gesehen reguläre Funktionen. Aber es gibt zwei Konventionen:

  1. Ihre Namen beginnen mit einem Großbuchstaben.
  2. Sie können nur mit dem Operator "new" ausgeführt werden.

Zum Beispiel:

let user = new User; // <-- 没有参数// 等同于let user = new User();复制代码
🎜Wenn eine Funktion mit dem Operator new ausgeführt wird, folgt sie den folgenden Schritten: 🎜
  1. Ein neues leeres Objekt ist Erstellt und diesem zugewiesen.
  2. Der Funktionskörper wird ausgeführt. Normalerweise ändert es dies und fügt ihm neue Attribute hinzu.
  3. Gibt den Wert von this zurück.
🎜Mit anderen Worten, new User(...) macht so etwas wie: 🎜
function User(name) {  this.name = name;  this.sayHi = function() {
    alert( "My name is: " + this.name );
  };
}let john = new User("John");

john.sayHi(); // My name is: John/*
john = {
   name: "John",
   sayHi: function() { ... }
}
*/复制代码
🎜So new User("Jack") Das Ergebnis von code> ist das gleiche Objekt: 🎜
function A() { ... }function B() { ... }let a = new A;let b = new B;

alert( a == b ); // true复制代码
🎜Wenn wir nun andere Benutzer erstellen möchten, können wir new User("Ann"), new User("Alice") usw. Viel kürzer und einfacher zu lesen, als jedes Mal die wörtliche Erstellung zu verwenden. 🎜🎜Dies ist der Hauptzweck von Konstruktoren – die Implementierung von wiederverwendbarem Objekterstellungscode. 🎜🎜Lassen Sie es uns noch einmal betonen – technisch gesehen kann jede Funktion als Konstruktor verwendet werden. Das heißt: Jede Funktion kann über new ausgeführt werden, wodurch der obige Algorithmus ausgeführt wird. „Großschreibung“ ist eine gängige Konvention, um deutlich zu machen, dass eine Funktion mit new ausgeführt wird. 🎜

new function() { ...

🎜Wenn wir viele Codezeilen haben, die ein einzelnes komplexes Objekt erstellen, können wir sie in einem Konstruktor kapseln, z Dies: 🎜
let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );复制代码
🎜Der Konstruktor kann nicht erneut aufgerufen werden, da er nirgendwo gespeichert, sondern nur erstellt und aufgerufen wird. Daher soll dieser Tipp den Code kapseln, der ein einzelnes Objekt erstellt, ohne dass es in Zukunft wiederverwendet werden muss. 🎜

Konstruktormustertest: new.target🎜
🎜Erweiterter Inhalt:🎜🎜Der in diesem Abschnitt behandelte Syntaxinhalt wird selten verwendet, es sei denn, Sie möchten um alles zu verstehen, ansonsten können Sie die Syntax einfach überspringen. 🎜
🎜Innerhalb einer Funktion können wir das Attribut new.target verwenden, um zu prüfen, ob sie mit new aufgerufen wurde. 🎜🎜Bei regulären Aufrufen ist es leer. Bei Aufrufen mit new entspricht es der Funktion: 🎜
let accumulator = new Accumulator(1); // 初始值 1accumulator.read(); // 添加用户输入的 valueaccumulator.read(); // 添加用户输入的 valuealert(accumulator.value); // 显示这些值的总和复制代码
🎜Es kann innerhalb der Funktion verwendet werden, um zu bestimmen, ob die Funktion über übergeben wird new Der von aufgerufene „Konstruktormodus“ ist immer noch der „reguläre Modus“, der nicht von new aufgerufen wird. 🎜🎜Wir können auch dafür sorgen, dass der new-Aufruf die gleiche Aufgabe wie ein normaler Aufruf erledigt, etwa so: 🎜rrreee🎜Dieser Ansatz wird manchmal in Bibliotheken verwendet, um die Syntax flexibler zu gestalten. Auf diese Weise funktioniert das Programm beim Aufrufen der Funktion unabhängig davon, ob sie new verwenden oder nicht. 🎜🎜Es überall zu verwenden ist jedoch keine gute Sache, da das Weglassen von new es schwierig macht, zu beobachten, was im Code passiert. Und durch new können wir alle wissen, dass dadurch ein neues Objekt erstellt wird. 🎜

Rückgabe des Konstruktors🎜🎜Normalerweise haben Konstruktoren keine return-Anweisung. Ihre Aufgabe ist es, alle notwendigen Dinge in this zu schreiben und diese automatisch in das Ergebnis umzuwandeln. 🎜🎜Wenn es jedoch eine return-Anweisung gibt, ist die Regel einfach: 🎜
  • Wenn return ein Objekt zurückgibt, dann geben Sie stattdessen dieses Objekt zurück von diesem.
  • Ignorieren, wenn return einen primitiven Typ zurückgibt.
🎜Mit anderen Worten: return mit einem Objekt gibt dieses Objekt zurück, in allen anderen Fällen wird this zurückgegeben. 🎜🎜Zum Beispiel überschreibt return hier this, indem es ein Objekt zurückgibt: 🎜rrreee🎜Hier ist ein Beispiel, bei dem return leer ist (oder wir können es Das Einfügen eines primitiven Typs danach hat keine Auswirkung): 🎜rrreee🎜Normalerweise haben Konstruktoren keine return-Anweisung. Hier erwähnen wir das besondere Verhalten zurückgegebener Objekte hauptsächlich der Vollständigkeit halber. 🎜

Lassen Sie die Klammern weg

🎜Übrigens, wenn keine Parameter vorhanden sind, können wir die Klammern nach new weglassen: 🎜rrreee🎜Nein Die Klammern müssen hier weggelassen werden. Wird als „guter Stil“ angesehen, die Syntax ist jedoch in der Spezifikation zulässig. 🎜🎜Methoden in Konstruktoren🎜🎜Die Verwendung von Konstruktoren zum Erstellen von Objekten bringt viel Flexibilität. Ein Konstruktor kann über Parameter verfügen, die definieren, wie das Objekt erstellt wird und was darin eingefügt werden soll. 🎜

当然,我们不仅可以将属性添加到 this 中,还可以添加方法。

例如,下面的 new User(name) 用给定的 name 和方法 sayHi 创建了一个对象:

function User(name) {  this.name = name;  this.sayHi = function() {
    alert( "My name is: " + this.name );
  };
}let john = new User("John");

john.sayHi(); // My name is: John/*
john = {
   name: "John",
   sayHi: function() { ... }
}
*/复制代码

类 是用于创建复杂对象的一个更高级的语法,我们稍后会讲到。

总结

  • 构造函数,或简称构造器,就是常规函数,但大家对于构造器有个共同的约定,就是其命名首字母要大写。
  • 构造函数只能使用 new 来调用。这样的调用意味着在开始时创建了空的 this,并在最后返回填充了值的 this

我们可以使用构造函数来创建多个类似的对象。

JavaScript 为许多内置的对象提供了构造函数:比如日期 Date、集合 Set 以及其他我们计划学习的内容。

对象,我们还会回来哒!

在本章中,我们只介绍了关于对象和构造器的基础知识。它们对于我们在下一章中,学习更多关于数据类型和函数的相关知识非常重要。

在我们学习了那些之后,我们将回到对象,在 info:prototypes 和 info:classes 章节中深入介绍它们。

作业题

先自己做题目再看答案。

1. 两个函数 — 一个对象

重要程度:⭐️⭐️

是否可以创建像 new A()==new B() 这样的函数 AB

function A() { ... }function B() { ... }let a = new A;let b = new B;

alert( a == b ); // true复制代码

如果可以,请提供一个它们的代码示例。

2. 创建 new Calculator

重要程度:⭐️⭐️⭐️⭐️⭐️

创建一个构造函数 Calculator,它创建的对象中有三个方法:

  • read() 使用 prompt 请求两个值并把它们记录在对象的属性中。
  • sum() 返回这些属性的总和。
  • mul() 返回这些属性的乘积。

例如:

let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );复制代码

3. 创建 new Accumulator

重要程度:⭐️⭐️⭐️⭐️⭐️

创建一个构造函数 Accumulator(startingValue)

它创建的对象应该:

  • 将“当前 value”存储在属性 value 中。起始值被设置到构造器 startingValue 的参数。
  • read() 方法应该使用 prompt 来读取一个新的数字,并将其添加到 value 中。

换句话说,value 属性是所有用户输入值与初始值 startingValue 的总和。

下面是示例代码:

let accumulator = new Accumulator(1); // 初始值 1accumulator.read(); // 添加用户输入的 valueaccumulator.read(); // 添加用户输入的 valuealert(accumulator.value); // 显示这些值的总和复制代码

相关免费学习推荐:JavaScript(视频)

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des JavaScript-Konstruktors und des „neuen“ Operators. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:Was ist jquery weui?Nächster Artikel:Was ist jquery weui?