23 schwierige Fragen für JavaScript-Interviews

Möchten Sie sich auf ein JavaScript-Interview vorbereiten und suchen nach Fragen zum Üben? Wenn ja - denken Sie daran, dass Ihre Suche beendet ist. Der Autor des Materials, dessen Übersetzung wir heute veröffentlichen, sagt, dass er mehr als zwei Dutzend Fragen zu JavaScript gesammelt hat, die für diejenigen bestimmt sind, die von einem Junior zu einem Senior werden möchten, für diejenigen, die ein Interview im Bereich der Front-End-Entwicklung erfolgreich bestehen und ein interessantes Angebot von erhalten möchten Der Arbeitgeber.


Bild

1. Erläutern Sie die Funktionen zur Überprüfung der JavaScript-Gleichstellung


Schwierigkeit: *


JavaScript verfügt über zwei Operatoren zum Überprüfen der Gleichheit von Werten. Der erste ist der sogenannte strikte Gleichheitsoperator. Der zweite ist der nicht strikte Gleichheitsoperator, mit dem die Arten der geprüften Mengen konvertiert werden können.

  • Der Operator ===für strikte Gleichheit ( ) überprüft die Werte auf Gleichheit, ohne Typkonvertierungen durchzuführen.
  • Der nicht strenge Gleichheitsoperator ( ==) überprüft die Werte auf Gleichheit und konvertiert sie in einen gemeinsamen Typ.

var a = "42";
var b = 42;

a == b;         // true
a === b;        // false

Hier sind einige Richtlinien für die Verwendung verschiedener Gleichstellungsprüfer in JavaScript:

  • Wenn einer der verglichenen Werte ein Wert sein kann trueoder false- versuchen Sie, den Operator zu meiden ==. Verwenden Sie einen Operator ===.
  • Verwenden Sie den Operator ===für den Fall, dass Sie mit den folgenden Werten arbeiten : 0, «»oder [](leeres Array).
  • In allen anderen Fällen können Sie den Operator sicher verwenden ==. Darüber hinaus ist dies nicht nur sicher, sondern vereinfacht auch den Code und verbessert seine Lesbarkeit.

Quelle

2. Geben Sie Beispiele für das Umwandeln in einen logischen Wertetyp, der nicht mit diesem Typ zusammenhängt


Schwierigkeit: ***


Das Wesentliche dieser Frage ist, herauszufinden, in welche Werte, wenn sie in einen logischen Typ umgewandelt werden false, und in welche umgewandelt werden true.

Hier ist eine Liste von Werten, die als "falsch" bezeichnet werden können. Sie werden beim Konvertieren in einen logischen Typ zu einem Wert false:

  • «» (leere Zeile).
  • 0, -0, NaN(Nicht eine Zahl).
  • null, undefined.

"Falsch" ist eine logische Bedeutung false.

Jeder Wert, der nicht in dieser Liste enthalten ist, wird bei der Konvertierung in einen logischen Typ zu true(solche Werte werden als "wahr" - wahr) bezeichnet. Zum Beispiel:

  • «hello».
  • 42.
  • [ ], [ 1, «2», 3 ](Arrays).
  • { }, { a: 42 }(Objekte).
  • function foo() { .. } (Funktionen).

"Wahr" ist auch eine logische Bedeutung true.

Quelle

3. Was ist IIFE?


Schwierigkeit: ***


IIFE (Sofort aufgerufener Funktionsausdruck) ist ein sofort aufgerufener Funktionsausdruck. Ein solcher Ausdruck wird unmittelbar nach der Erstellung ausgeführt.

(function IIFE(){
    console.log( "Hello!" );
})();
// "Hello!"

Dieses Muster wird häufig verwendet, um eine Verschmutzung des globalen Namespace zu verhindern. Tatsache ist, dass in IIFE deklarierte Variablen (wie bei jeder anderen normalen Funktion) außerhalb dieser Funktion unsichtbar sind.

Quelle

4. Wann sollte ich die in ES6 angezeigten Pfeilfunktionen verwenden?


Schwierigkeit: ***


Hier sind einfache Regeln für die Verwendung der verschiedenen Möglichkeiten zum Deklarieren von Funktionen, die ich beim Entwickeln von Code für Umgebungen befolge, die ES6 und neuere Standards unterstützen:

  • Verwenden Sie das Schlüsselwort functionim globalen Bereich und für Eigenschaften Object.prototype.
  • Verwenden Sie das Schlüsselwort functionfür Objektkonstruktoren.
  • Verwenden Sie in anderen Fällen die Pfeilfunktionen.

Wie Sie sehen können, wird empfohlen, Pfeilfunktionen fast überall zu verwenden. Es gibt mehrere Gründe für diesen Zustand:

  • Bequeme Arbeit mit Kontext. Pfeilfunktionen verwenden den Wert des thisumgebenden Kontexts, ohne einen eigenen zu haben this. Wenn solche Funktionen nacheinander verwendet werden, ohne gewöhnliche Funktionen in komplexen Konstruktionen zu verwenden, gewährleistet dies eine sichere Arbeit mit dem Kontext.
  • Kompaktheit. Der Pfeilfunktionscode ist einfacher einzugeben und leichter zu lesen. Vielleicht erscheint Ihnen dieser Vorteil von Pfeilfunktionen gegenüber gewöhnlichen kontrovers und hängt von der Sichtweise jedes einzelnen Entwicklers ab.
  • Klarheit des Codes. Wenn fast der gesamte Code durch Pfeilfunktionen dargestellt wird, wird jede gewöhnliche Funktion in einem solchen Code durch Erstellen eines eigenen Kontexts unterschieden. Mit den Pfeilfunktionen erstellt der Programmierer einen verständlicheren Code, mit dem einfacher gearbeitet werden kann als mit Code ohne Pfeilfunktionen this.

Quelle

5. Was ist der Unterschied zwischen ES6-Klassen und Funktionskonstruktoren?


Schwierigkeit: ***


Schauen wir uns zuerst einige Beispiele an.

Konstruktorfunktion:

function Person(name) {
  this.name = name;
}

ES6-Klasse:

class Person {
  constructor(name) {
    this.name = name;
  }
}

Beim Erstellen einfacher Objekte sehen die für diesen Zweck verwendeten Konstruktoren und Klassen sehr ähnlich aus.

Der Hauptunterschied zwischen Konstruktoren und Klassen tritt bei der Verwendung der Vererbung auf. Wenn wir eine Klasse erstellen müssen, die eine StudentUnterklasse der Klasse ist, Personund dieser neuen Klasse ein Feld hinzufügen müssen studentId, sehen der Code, in dem die Konstruktoren verwendet werden, und der Code, in dem die Klassen verwendet werden, so aus.

Konstruktorfunktion:

function Student(name, studentId) {
  //      ,   .
  Person.call(this, name);

  //    .
  this.studentId = studentId;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

ES6-Klasse:

class Student extends Person {
  constructor(name, studentId) {
    super(name);
    this.studentId = studentId;
  }
}

Quelle

6. Erzählen Sie uns von der Function.prototype.bind () -Methode.


Schwierigkeit: ***


So zitieren Sie MDN: „Die Methode bind()erstellt eine neue Funktion, die beim Aufruf den angegebenen thisWert als Ausführungskontext festlegt . Die Menge der Argumente wird auch an die Methode übergeben, die vor den Argumenten festgelegt wird, die beim Aufruf an die gebundene Funktion übergeben werden. “

Ich glaube diese Methode. bind()Besonders nützlich zum Binden von Werten thisin Klassenmethoden, die an andere Funktionen übergeben werden müssen. Diese Technik wird häufig in React-Komponenten verwendet.

Quelle 

7. Wofür werden häufig anonyme Funktionen verwendet?


Schwierigkeit: ***


Anonyme Funktionen werden verwendet, um IIFE-Konstruktionen zu erstellen, die deklarierten Variablen, die den globalen Bereich nicht verschmutzen.

(function() {
  // - .
})();

Anonyme Funktionen werden als Rückruffunktionen verwendet, die nur an einer Stelle des Programms verwendet werden. Der Code sieht autarker und lesbarer aus, wenn der Rückruf direkt an der Stelle angekündigt wird, an der er verwendet wird. Dadurch entfällt die Notwendigkeit, den Code auf der Suche nach dem Funktionskörper zu betrachten.

setTimeout(function() {
  console.log('Hello world!');
}, 1000);

Anonyme Funktionen werden bequem in Konstruktionen verwendet, die für den funktionalen Programmierstil spezifisch sind, oder bei der Arbeit mit Bibliotheken wie Lodash (dieser Anwendungsfall ähnelt ihrer Verwendung als Rückruf).

const arr = [1, 2, 3];
const double = arr.map(function(el) {
  return el * 2;
});
console.log(double); // [2, 4, 6]

Quelle

8. Was ist der Unterschied zwischen der Object.freeze () -Methode und dem const-Schlüsselwort?


Schwierigkeit: ***


Schlüsselwort constund Methode Object.freeze()sind völlig verschiedene Dinge.

Das Schlüsselwort constgilt für Bindungen (für "Variablen"). Es wird eine unveränderliche Bindung erstellt, dh es ist constunmöglich, etwas Neues an eine Variable (Konstante) zu binden, die mit einem Schlüsselwort deklariert wurde . Einer Konstante kann kein neuer Wert zugewiesen werden.

const person = {
    name: "Leonardo"
};
let animal = {
    species: "snake"
};
person = animal; // Uncaught TypeError: Assignment to constant variable.

Die Methode Object.freeze()arbeitet mit Werten. Oder besser gesagt mit Objektwerten. Es macht das Objekt unveränderlich, was vor Wertänderungen der Eigenschaften dieses Objekts schützt.

let person = {
    name: "Leonardo"
};
Object.freeze(person);
person.name = "Lima"; // Uncaught TypeError: Cannot assign to read only property 'name' of object
console.log(person);

Bitte beachten Sie, dass die Fehlermeldung im strengen Modus angezeigt wird. Im normalen Modus funktioniert das Ändern der Eigenschaft eines "eingefrorenen" Objekts einfach nicht.

Quelle

9. Was ist ein "Generator"?


Schwierigkeit: ***


Generatoren sind Funktionen, aus denen Sie „austreten“ und in die Sie bei Bedarf „eintreten“ können. Ihr Kontext (variable Bindungen) wird zwischen den Sitzungen des "Eintritts" in sie beibehalten. Generatoren werden mit einem Schlüsselwort deklariert function*. Eine solche Funktion führt beim ersten Aufruf den Code nicht aus und gibt ein spezielles Objekt zurück, einen Generator, mit dem Sie seine Ausführung steuern können. Um den nächsten vom Generator ausgegebenen Wert zu erhalten, müssen Sie dessen Methode aufrufen next(). Aus diesem Grund wird der Funktionscode ausgeführt, bis er auf ein Schlüsselwort stößt yield, das einen Wert zurückgibt.

Die Generatorfunktion kann beliebig oft aufgerufen werden. Jedes Mal, wenn ein neuer Generator zurückkehrt. Jeder Generator kann jedoch nur einmal umgangen werden.

function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
    let iterationCount = 0;
    for (let i = start; i < end; i += step) {
        iterationCount++;
        yield i;
    }
    return iterationCount;
}

Quelle

10. Wann sollten Generatoren verwendet werden?


Schwierigkeit: ***


Kurz gesagt, um die wichtigsten nützlichen Merkmale von Generatoren zu beschreiben, stellt sich heraus, dass sie wie folgt sind:

  • Der Code, in dem der Generator verwendet wird, bestimmt den Zeitpunkt, zu dem der nächste Wert empfangen wird. Der Generator ist nur für die Rückgabe von Werten verantwortlich, er wird von außen gesteuert.
  • Es gibt asynchrone Generatoren. Mit ihnen können Sie mit asynchronen Datenströmen arbeiten.

Die Hauptsache bei Generatoren ist, dass Sie den nächsten vom Generator zurückgegebenen Wert nur erhalten können, wenn er in Code benötigt wird, der den Generator verwendet. Generatoren geben nicht alles auf einmal zurück. In einigen Situationen kann diese Funktion sehr praktisch sein.

Quelle

11. Was ist das „Erhöhen von Variablen“?


Schwierigkeit: ****


Das Konzept des "Erhöhens von Variablen" besteht im Wesentlichen darin, dass Anzeigen an die Spitze des aktuellen Bereichs "steigen". Infolgedessen kann die Variable vor ihrer Deklaration verwendet werden. Es werden nur Variablendeklarationen ausgelöst, nicht jedoch deren Initialisierungscode. Beachten Sie, dass sich das Verhalten von Variablen, die mit dem Schlüsselwort deklariert wurden, varvom Verhalten von Variablen und Konstanten unterscheidet, die mit letund deklariert wurden const.

Quelle

12. Was wird der folgende Code ausgeben?


Schwierigkeit: ****


var output = (function(x) {
  delete x;
  return x;
})(0);

console.log(output);

Dieser Code wird ausgegeben 0. Der Operator wird deleteverwendet, um die Eigenschaften von Objekten zu löschen. Und x- dies ist keine Objekteigenschaft - es ist eine lokale Variable. Der Operator beeinflusst deletekeine lokalen Variablen.

Quelle

13. Was wird der folgende Code ausgeben?


Schwierigkeit: ****


var Employee = {
  company: 'xyz'
}
var emp1 = Object.create(Employee);
delete emp1.company
console.log(emp1.company);

Dieser Code wird ausgegeben xyz. Eine Eigenschaft companyist keine Eigenschaft eines Objekts emp1, sondern eine Eigenschaft seines Prototyps. Der Operator deletelöscht nicht die Prototyp-Eigenschaften von Objekten. Ein Objekt emp1hat keine eigene Eigenschaft company. Sie können dies überprüfen, indem Sie:

console.log(emp1.hasOwnProperty('company')); // false

Wenn wir diese Eigenschaft noch entfernen müssen, können Sie dies entweder durch direkte Kontaktaufnahme mit dem Objekt Employee( delete Employee.company) oder durch Kontaktaufnahme mit dem Prototyp des Objekts emp1über seine Eigenschaft __proto__( delete emp1.__proto__.company) tun .

Quelle

14. Erzählen Sie uns etwas über das Muster des Prototypentwurfs.


Schwierigkeit: ****


Der Prototyp ist ein generisches Entwurfsmuster. Es wird verwendet, um Objekte zu erstellen. Mit ihm erstellte Objekte enthalten Werte, die von ihrem Prototyp (vom Beispielobjekt) kopiert wurden. Diese Vorlage wird auch als Eigenschaftenvorlage bezeichnet.

Ein Beispiel für die Verwendung des Musters „Prototyp“ ist die Initialisierung bestimmter Objekte mit in der Datenbank gespeicherten Standardwerten. Solche im Prototyp aufgezeichneten Werte werden ohne Zugriff auf die Datenbank in neue Objekte kopiert.

Es ist zu beachten, dass dieses Muster in klassischen Sprachen selten verwendet wird. JavaScript verwendet ein Prototyp-Vererbungsmodell. Dieses Muster wird bei der Gestaltung neuer Objekte und ihrer Prototypen verwendet.

Quelle

15. Was ist eine „temporäre Totzone“ in ES6?


Schwierigkeit: ****


Der ES6 hob Variablen und Konstanten auf, die mit den Schlüsselwörtern deklariert wurden, letund const(dies erfolgt und der Aufstieg der Entität, die mit Schlüsselwörtern deklariert wurde var, classund function). Der Code verfügt jedoch über eine Zone, die von der Eingabe des Bereichs bis zur Deklaration einer Variablen oder Konstante reicht. Beim Zugriff auf eine Variable oder Konstante in dieser Zone wird ein Fehler generiert. Dies ist die "Temporal Dead Zone" (TDZ).

//console.log(aLet)  //  ReferenceError

let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10

In diesem Beispiel endet die TDZ nach der Deklaration aLet, jedoch nicht nach der Zuweisung des aLetWerts.

Quelle

16. Können Sie den Hauptunterschied zwischen den Array-Methoden forEach () und map () beschreiben? In welchen Situationen würden Sie eine dieser Methoden einer anderen vorziehen?


Schwierigkeit: ****


Um den Unterschied zwischen diesen Methoden zu verstehen, sprechen wir über die Funktionen der einzelnen Methoden.

So funktioniert es .forEach():

  • Es iteriert über die Elemente des Arrays.
  • Es führt die Rückruffunktion aus, die für jedes Element des Arrays an ihn übergeben wird.
  • Es gibt nichts zurück.

const a = [1, 2, 3];
const doubled = a.forEach((num, index) => {
  //  -  num /  index.
});

// doubled = undefined

Hier ist eine kurze Beschreibung der Methode .map():

  • Es iteriert über die Elemente des Arrays.
  • Es konvertiert jedes Element des ursprünglichen Arrays in ein Element des neuen Arrays und ruft die an es übergebene Funktion für jedes Element des ursprünglichen Arrays auf.

const a = [1, 2, 3];
const doubled = a.map(num => {
  return num * 2;
});

// doubled = [2, 4, 6]

Als Ergebnis stellt sich heraus, dass der Hauptunterschied zwischen .forEach()und darin .map()besteht, dass .map()ein neues Array zurückgegeben wird. Wenn Sie das Ergebnis der Konvertierung der Elemente des ursprünglichen Arrays erhalten möchten, ohne dieses Array zu ändern, sollten Sie auswählen .map(). Wenn Sie nur die Elemente des Arrays durchlaufen müssen, können Sie es verwenden .forEach().

Quelle

17. Was ist der Unterschied zwischen einer nicht deklarierten Variablen, einer Variablen mit einem Nullwert und einer nicht definierten Variablen? Wie überprüfe ich eine Variable auf die Tatsache, dass sie nicht deklariert sowie null und undefiniert ist?


Schwierigkeit: ****


Eine nicht deklarierte Variable wird erstellt, wenn ein Wert einem Bezeichner zugewiesen wird, der zuvor nicht mit oder deklariert varwurde . Nicht deklarierte Variablen werden im globalen Bereich außerhalb des aktuellen Bereichs deklariert. Im strengen Modus wird eine Ausnahme ausgelöst, wenn versucht wird, einer nicht deklarierten Variablen einen Wert zuzuweisen . Die Verwendung nicht deklarierter Variablen wird nicht empfohlen - ebenso wie die Verwendung globaler Variablen nicht empfohlen wird. Sie sollten auf jeden Fall vermieden werden. Verwenden Sie den Block, um sich vor den Folgen der Verwendung nicht deklarierter Variablen zu schützen .letconstReferenceErrortry/catch

function foo() {
  x = 1; //     ReferenceError
}

foo();
console.log(x); // 1

Eine Variable, die enthält, undefinedist eine deklarierte Variable, der kein Wert zugewiesen ist. Wert undefinedbildet einen eigenen Datentyp. Wenn die Funktion nichts zurückgibt und das Ergebnis ihres Aufrufs in eine Variable geschrieben wird, fällt sie in diese Variable undefined. Um eine Prüfung für zu organisieren undefined, können Sie den Operator für strikte Gleichheit ( ===) oder den Operator verwenden typeof, der eine Zeichenfolge zurückgibt undefined. Bitte beachten Sie, dass , wenn für die Überprüfung, undefinedSie nicht den Nicht-strikten Gleichheitsoperator (verwenden sollen ==), da es die Auffassung , undefinedund Werte gleich sein null.

var foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === 'undefined'); // true

console.log(foo == null); // true.        undefined!

function bar() {}
var baz = bar();
console.log(baz); // undefined

Eine Variable, die einen Wert enthält, nullmuss explizit auf diesen Wert gesetzt werden. Es symbolisiert das Fehlen von Bedeutung und unterscheidet sich von undefined-variable dadurch, dass der darin enthaltene Wert explizit zugewiesen wurde. Um den Wert zu überprüfen null, reicht es aus, den strengen Gleichheitsoperator zu verwenden. Um zu prüfen null, wie im Fall der Prüfung undefined, sollte man nicht den nicht strengen Gleichheitsoperator verwenden, der die Werte von nullund gleich berücksichtigt undefined.

var foo = null;
console.log(foo === null); // true
console.log(typeof foo === 'object'); // true

console.log(foo == undefined); // true        null!

Ich versuche, Variablen niemals in einem nicht deklarierten Zustand oder in einem Zustand zu belassen, in dem sie deklariert sind, aber ihnen wird kein Wert explizit zugewiesen. Wenn ich nicht unmittelbar nach ihrer Deklaration einen Wert in eine Variable schreiben werde, schreibe ich darauf null. Wenn Sie einen Linter verwenden, werden normalerweise Fälle gemeldet, in denen nicht deklarierte Variablen verwendet werden.

Quelle

18. Erzählen Sie uns von dem Designmodul "Modul öffnen"


Schwierigkeit: *****


Die Vorlage "Revealing Module" ist eine Variation der Vorlage "Module". Der Zweck der Verwendung dieses Musters besteht darin, die Kapselung zu unterstützen und einige Eigenschaften und Methoden zu ermitteln, die im Objektliteral zurückgegeben werden. So sieht die direkte Implementierung dieser Vorlage aus:

var Exposer = (function() {
  var privateVariable = 10;

  var privateMethod = function() {
    console.log('Inside a private method!');
    privateVariable++;
  }

  var methodToExpose = function() {
    console.log('This is a method I want to expose!');
  }

  var otherMethodIWantToExpose = function() {
    privateMethod();
  }

  return {
      first: methodToExpose,
      second: otherMethodIWantToExpose
  };
})();

Exposer.first();        // : This is a method I want to expose!
Exposer.second();       // : Inside a private method!
Exposer.methodToExpose; // undefined

Der offensichtliche Nachteil dieser Vorlage besteht darin, dass Sie bei der Verwendung keine privaten Methoden verwenden können.

Quelle

19. Was ist der Unterschied zwischen Map- und WeakMap-Objekten?


Schwierigkeit: *****


Diese Objekte verhalten sich unterschiedlich, wenn eine Variable, die einen Verweis auf ein Objekt enthält, das der Schlüssel eines der Schlüssel / Wert-Paare ist, nicht verfügbar ist. Hier ist ein Beispiel:

var map = new Map();
var weakmap = new WeakMap();

(function() {
    var a = {
        x: 12
    };
    var b = {
        y: 12
    };

    map.set(a, 1);
    weakmap.set(b, 2);
})()

Nach Abschluss der Ausführung von IIFE haben wir keinen Zugriff mehr auf die Objekte aund b. Daher entfernt der Garbage Collector den Schlüssel baus weakmapdem Speicher und löscht ihn. Der Inhalt mapbleibt aber gleich.

Infolgedessen stellt sich heraus, dass Objekte WeakMapes dem Garbage Collector ermöglichen, die Datensätze zu entfernen, auf die in externen Variablen nicht verwiesen wird. Objekte mapspeichern Schlüssel / Wert-Paare unabhängig vom Vorhandensein oder Fehlen externer Schlüsselreferenzen. Gleiches gilt für die Implementierung der Datenstruktur Mapmit gewöhnlichen Arrays. Die WeakMap"schwachen" Schlüsselreferenzen werden verwendet. Sie stören den Betrieb des Garbage Collectors nicht, wenn keine anderen Verweise auf das als Schlüssel verwendete Objekt vorhanden sind.

Quelle

20. Wie werden Parameter an die JavaScript-Funktion übergeben: als Referenz oder als Wert?


Schwierigkeit: *****


Parameter werden immer als Wert übergeben, aber Verweise auf Objekte werden in Variablen geschrieben, die Objekte darstellen. Wenn ein Objekt an eine Funktion übertragen und die Eigenschaft dieses Objekts geändert wird, wird diese Änderung daher auch dann im Objekt gespeichert, wenn die Funktion beendet wird. Infolgedessen besteht das Gefühl, dass die Parameter in der Funktion als Referenz übergeben werden. Wenn Sie jedoch den Wert der Variablen ändern, die das Objekt darstellt, wirkt sich diese Änderung nicht auf Objekte aus, die sich außerhalb der Funktion befinden.

Hier ist ein Beispiel:

function changeStuff(a, b, c)
{
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num);
console.log(obj1.item);
console.log(obj2.item);

Dieser Code gibt Folgendes aus:

10
changed
unchanged

Quelle

21. Wie organisiere ich ein „Deep Freeze“ eines Objekts?


Schwierigkeit: *****


Um ein "Deep Freezing" eines Objekts mithilfe von zu ermöglichen Object.freeze(), müssen Sie eine rekursive Funktion erstellen, die die Eigenschaften des Objekts "einfriert", die auch Objekte sind.

Hier ist ein Beispiel für ein gewöhnliches „Einfrieren“ eines Objekts:

let person = {
    name: "Leonardo",
    profession: {
        name: "developer"
    }
};
Object.freeze(person); //   
person.profession.name = "doctor";
console.log(person); // { name: 'Leonardo', profession: { name: 'doctor' } }

Hier ist das "Tiefkühlen":

function deepFreeze(object) {
    let propNames = Object.getOwnPropertyNames(object);
    for (let name of propNames) {
        let value = object[name];
        object[name] = value && typeof value === "object" ?
            deepFreeze(value) : value;
    }
    return Object.freeze(object);
}
let person = {
    name: "Leonardo",
    profession: {
        name: "developer"
    }
};
deepFreeze(person);
person.profession.name = "doctor"; // TypeError: Cannot assign to read only property 'name' of object

Die Fehlermeldung wird nur im strengen Modus angezeigt. Im normalen Modus ändert sich der Wert nicht ohne Fehlermeldungen.

Quelle

22. Warum haben JavaScript-Programmierer Probleme, dieses Schlüsselwort zu verwenden?


Schwierigkeit: *****


Das Wichtigste, was Sie verstehen müssen, thisist, dass Funktionen keinen festen Wert haben this. Dieser Wert hängt davon ab, wie die Funktion aufgerufen wird. Wenn wir sagen, dass eine Funktion mit einem bestimmten Wert aufgerufen wird this, bedeutet dies, dass dieser Wert nicht während der Deklaration der Funktion, sondern während ihres Aufrufs bestimmt wird. Hier sind einige Funktionen this:

  • Wenn die Funktion in der üblichen Form aufgerufen wird (dh mit dem Ansichtskonstrukt someFunc()), thisverweist sie auf das globale Objekt (im Browser dies window). Wenn der Code im strengen Modus ausgeführt wird, wird ein thisWert in geschrieben undefined.
  • Wenn die Funktion als Methode eines Objekts aufgerufen wird, wird das Schlüsselwort thisdurch das Objekt dargestellt, zu dem die Methode gehört.
  • call apply, this , call apply.
  • , this .
  • , new, this , prototype -.
  • Wenn die Funktion mit der Bindungsmethode erstellt wurde , wird das thisFunktionsschlüsselwort fest an den Wert gebunden, der bindals erstes Argument übergeben wurde. Dies ist die einzige Ausnahme von der Regel, dass Funktionen keinen fest codierten Wert haben this. Mit erstellte Funktionen bindsind unveränderlich this.

Quelle

23. Vergleichen Sie die Verwendung des Konstrukts async / await und der Generatoren, um dieselbe Funktionalität zu implementieren


Schwierigkeit: *****


  • Wenn Sie einen Generator mit einer Methode iterieren, gibt .next()jeder Aufruf dieser Methode einen einzelnen Wert mit dem Schlüsselwort zurück yield. Bei Verwendung des Konstrukts async / await werden Warteausdrücke nacheinander ausgeführt.
  • Das asynchrone / wartende Design vereinfacht die Implementierung eines bestimmten Generator-Anwendungsfalls.
  • Die vom Generator zurückgegebenen Werte haben immer die Form {value: X, done: Boolean}, und asynchrone Funktionen geben die mit dem Wert aufgelösten Versprechen zurück Xoder schlagen fehl.
  • Eine asynchrone Funktion kann mithilfe von Versprechungen in einen Generator umgewandelt werden. Das Folgende ist ein Beispiel für eine solche Konvertierung.

Hier ist die asynchrone Funktion:

//  
async function init() {
    const res1 = await doTask1();
    console.log(res1);

    const res2 = await doTask2(res1);
    console.log(res2);

    const res3 = await doTask3(res2);
    console.log(res3);

    return res3;
}

init();

Hier ist ein ähnlicher Generator.

//    
function runner(genFn) {
    const itr = genFn();

    function run(arg) {
        let result = itr.next(arg);

        if (result.done) {
            return result.value;
        } else {
            return Promise.resolve(result.value).then(run);
        }
    }

    return run;
}

//   runner    
runner(function* () {
    const res1 = await doTask1();
    console.log(res1);

    const res2 = await doTask2(res1);
    console.log(res2);

    const res3 = await doTask3(res2);
    console.log(res3);

    return res3;
});

Quelle

Liebe Leser! Welche JavaScript-Fragen haben Sie während Ihrer Interviews gestellt?


All Articles