Heim > Web-Frontend > js-Tutorial > 7 Interviewfragen zu Schließungen in JavaScript, können Sie sie beantworten?

7 Interviewfragen zu Schließungen in JavaScript, können Sie sie beantworten?

青灯夜游
Freigeben: 2021-04-14 09:22:44
nach vorne
5932 Leute haben es durchsucht

7 Interviewfragen zu Schließungen in JavaScript, können Sie sie beantworten?

Verwandte Empfehlungen: Zusammenfassung der großen Front-End-Interviewfragen 2021 (Sammlung)

Jeder JavaScript-Programmierer muss wissen, was ein Abschluss ist. In einem JavaScript-Interview werden Sie höchstwahrscheinlich nach dem Konzept von Abschlüssen gefragt.

Im Folgenden finden Sie 7 herausfordernde Interviewfragen zu JavaScript-Abschlüssen.

Schauen Sie sich nicht die Antworten an und führen Sie den Code nicht aus, um zu sehen, wie gut Sie sind. Die Beantwortung dieser Fragen dauert etwa eine halbe Stunde.

1. Scope

hat die folgenden Funktionen clickHandler, immediate und delayedReload: clickHandlerimmediatedelayedReload

let countClicks = 0;
button.addEventListener('click', function clickHandler() {
  countClicks++;
});
const result = (function immediate(number) {
  const message = `number is: ${number}`;
  return message;
})(100);
setTimeout(function delayedReload() {
  location.reload();
}, 1000);
Nach dem Login kopieren

这3个函数中哪个能够访问外部范围变量?

答案

  • clickHandler 能够从外部作用域访问变量 countClicks

  • immediate 无法访问外部作用域中的任何变量。

  • delayedReload 从全局作用域(也就是最外层作用域)中访问全局变量 location

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

2.  丢失的参数

下列代码输出什么:

(function immediateA(a) {
  return (function immediateB(b) {
    console.log(a); // => ?
  })(1);
})(0);
Nach dem Login kopieren

答案

输出为:0

用参数 0 调用 immediateA,因此 a 参数为 0

immediateB 函数嵌套在 immediateA 函数中,是一个闭包,它从外部 immediateA 作用域中得到 a 变量,其中 a0。因此 console.log(a) 的输出为 0

3. 谁是谁

下面的代码将会输出什么内容?

let count = 0;
(function immediate() {
  if (count === 0) {
    let count = 1;
    console.log(count); // 输出什么?
  }
  console.log(count); // 输出什么?
})();
Nach dem Login kopieren

答案

输出 10

第一个语句  let count = 0 声明了一个变量 count

immediate() 是一个闭包,它从外部作用域得到 count 变量。在 immediate()  函数作用域内, count0

但是,在条件内,另一个 let count = 1 声明了局部变量 count,该变量覆盖了作用域之外的 count。第一个 console.log(count) 输出 1

第二个 console.log(count) 输出为 0 ,因为这里的 count 变量是从外部作用域访问的。

4. 棘手的闭包

下列代码输出什么:

for (var i = 0; i < 3; i++) {
  setTimeout(function log() {
    console.log(i); // => ?
  }, 1000);
}
Nach dem Login kopieren

答案

输出:3, 3, 3

代码分为两个阶段执行。

阶段1

  1. for() 重复 3 次。在每次循环都会创建一个新函数 log(),该函数将捕获变量 isetTimout() 安排log() 在 1000 毫秒后执行。
  2. for() 循环完成时,变量 i 的值为 3

阶段2

第二阶段发生在 1000ms 之后:

  1. setTimeout() 执行预定的 log() 函数。 log() 读取变量 i 当前的值 3,并输出 3

所以输出 3, 3, 3

5. 错误的信息

下面的代码将会输出什么:

function createIncrement() {
  let count = 0;
  function increment() { 
    count++;
  }

  let message = `Count is ${count}`;
  function log() {
    console.log(message);
  }
  
  return [increment, log];
}

const [increment, log] = createIncrement();
increment(); 
increment(); 
increment(); 
log(); // => ?
Nach dem Login kopieren

答案

输出:'Count is 0'

increment() 函数被调用 3 次,将 count 增加到 3

message 变量存在于 createIncrement() 函数的作用域内。其初始值为 'Count is 0'。但即使 count 变量已经增加了几次,message 变量的值也始终为 'Count is 0'

log() 函数是一个闭包,它从 createIncrement() 作用域中获取 message 变量。 console.log(message) 输出录'Count is 0'到控制台。

6. 重新封装

下面的函数 createStack() 用于创建栈结构:

function createStack() {
  return {
    items: [],
    push(item) {
      this.items.push(item);
    },
    pop() {
      return this.items.pop();
    }
  };
}

const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); // => 5

stack.items; // => [10]
stack.items = [10, 100, 1000]; // 栈结构的封装被破坏了
Nach dem Login kopieren

它能正常工作,但有一个小问题,因为暴露了 stack.items 属性,所以任何人都可以直接修改 items 数组。

这是一个大问题,因为它破坏了栈的封装:应该只有 push()pop() 方法是公开的,而 stack.items

function createStack() {
  // 把你的代码写在这里
}

const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); // => 5

stack.items; // => undefined
Nach dem Login kopieren
Nach dem Login kopieren
Welche dieser 3 Funktionen können sein? Auf externe Bereichsvariable zugegriffen? 🎜

🎜Answer🎜

  • 🎜clickHandler kann auf die Variable countClicks. 🎜
  • 🎜immediate kann nicht auf Variablen im äußeren Bereich zugreifen. 🎜
  • 🎜delayedReload greift aus dem globalen Bereich (also dem äußersten Bereich) auf die globale Variable location zu. 🎜
🎜Empfohlene Tutorials: Javascript Video-Tutorial🎜🎜🎜🎜2. Fehlende Parameter🎜🎜🎜Was bewirkt der folgende Code? Code >0 ruft immediateA auf, daher ist der Parameter a 0. 🎜🎜Die Funktion immediateB ist in der Funktion immediateA verschachtelt und ein Abschluss, der aimmediateA erhält. code>-Variable, wobei a 0 ist. Daher ist die Ausgabe von console.log(a) 0. 🎜🎜🎜3. Wer ist wer? 🎜🎜🎜Was wird der folgende Code ausgeben? 🎜
function createStack() {
  const items = [];
  return {
    push(item) {
      items.push(item);
    },
    pop() {
      return items.pop();
    }
  };
}

const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); // => 5

stack.items; // => undefined
Nach dem Login kopieren
Nach dem Login kopieren

🎜Antwort🎜

🎜Ausgabe 1 und 0🎜🎜Die erste Anweisung let count = 0 wird als A deklariert Variable anzahl. 🎜🎜immediate() ist ein Abschluss, der die Variable count aus dem äußeren Bereich abruft. Innerhalb des Funktionsumfangs immediate() ist count 0. 🎜🎜Allerdings deklariert innerhalb der Bedingung ein weiterer let count = 1 die lokale Variable count, die den count außerhalb des Gültigkeitsbereichs > überschreibt. Der erste console.log(count) gibt 1 aus. 🎜🎜Die zweite Ausgabe von console.log(count) ist 0, da hier vom äußeren Bereich aus auf die Variable count zugegriffen wird. 🎜🎜🎜4. Knifflige Abschlüsse 🎜🎜🎜Was bewirkt der folgende Code? 3. 🎜🎜Der Code wird in zwei Schritten ausgeführt. 🎜🎜🎜Phase 1🎜🎜
  1. for() 3 Mal wiederholen. Bei jedem Schleifendurchlauf wird eine neue Funktion log() erstellt, die die Variable i erfasst. setTimout() plant die Ausführung von log() nach 1000 Millisekunden.
  2. Wenn die for()-Schleife abgeschlossen ist, ist der Wert der Variablen i 3.
🎜🎜Phase 2🎜🎜🎜Die zweite Phase erfolgt nach 1000 ms: 🎜
  1. setTimeout() Führe den geplanten log() Funktion. <code> log() liest den aktuellen Wert der Variablen i 3 und gibt 3
aus 🎜Die Ausgabe ist also 3, 3, 3. 🎜🎜🎜5. Fehlermeldung 🎜🎜🎜Was wird der folgende Code ausgeben: 🎜
function multiply(num1, num2) {
  // 把你的代码写在这里...
}
Nach dem Login kopieren
Nach dem Login kopieren

🎜Antwort🎜

🎜Ausgabe: 'Count is 0'🎜🎜 Die Funktion increment() wird dreimal aufgerufen, wodurch count auf 3 erhöht wird. 🎜🎜Die Variable message existiert im Rahmen der Funktion createIncrement(). Sein Anfangswert ist 'Count is 0'. Aber auch wenn die Variable count mehrmals erhöht wurde, ist der Wert der Variablen message immer 'Count is 0'. 🎜🎜Die Funktion log() ist ein Abschluss, der die Variable message aus dem Bereich createIncrement() abruft. console.log(message) gibt 'Count is 0' an die Konsole aus. 🎜🎜🎜6. Neu verpacken 🎜🎜🎜Die folgende Funktion createStack() wird verwendet, um die Stapelstruktur zu erstellen: 🎜
multiply(4, 5); // => 20
multiply(3, 3); // => 9

const double = multiply(2);
double(5);  // => 10
double(11); // => 22
Nach dem Login kopieren
Nach dem Login kopieren
🎜Es funktioniert gut, aber es gibt ein kleines Problem, weil der stack ist die exponierte .items-Eigenschaft, sodass jeder das items-Array direkt ändern kann. 🎜🎜Dies ist ein großes Problem, da dadurch die Kapselung des Stapels unterbrochen wird: Nur die Methoden push() und pop() sollten öffentlich sein, und stack. Auf die Elemente oder andere Details kann nicht zugegriffen werden. 🎜

使用闭包的概念重构上面的栈实现,这样就无法在 createStack() 函数作用域之外访问 items 数组:

function createStack() {
  // 把你的代码写在这里
}

const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); // => 5

stack.items; // => undefined
Nach dem Login kopieren
Nach dem Login kopieren

答案

以下是对 createStack() 的重构:

function createStack() {
  const items = [];
  return {
    push(item) {
      items.push(item);
    },
    pop() {
      return items.pop();
    }
  };
}

const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); // => 5

stack.items; // => undefined
Nach dem Login kopieren
Nach dem Login kopieren

items 已被移至 createStack() 作用域内。

这样修改后,从 createStack() 作用域的外部无法访问或修改 items 数组。现在 items 是一个私有变量,并且栈被封装:只有 push()pop() 方法是公共的。

push()pop() 方法是闭包,它们从 createStack() 函数作用域中得到 items 变量。

7. 智能乘法

编写一个函数  multiply() ,将两个数字相乘:

function multiply(num1, num2) {
  // 把你的代码写在这里...
}
Nach dem Login kopieren
Nach dem Login kopieren

要求:

如果用 2 个参数调用 multiply(num1,numb2),则应返回这 2 个参数的乘积。

但是如果用 1个参数调用,则该函数应返回另一个函数: const anotherFunc = multiply(num1) 。返回的函数在调用 anotherFunc(num2)  时执行乘法  num1 * num2

multiply(4, 5); // => 20
multiply(3, 3); // => 9

const double = multiply(2);
double(5);  // => 10
double(11); // => 22
Nach dem Login kopieren
Nach dem Login kopieren

答案

以下是  multiply()  函数的一种实现方式:

function multiply(number1, number2) {
  if (number2 !== undefined) {
    return number1 * number2;
  }
  return function doMultiply(number2) {
    return number1 * number2;
  };
}

multiply(4, 5); // => 20
multiply(3, 3); // => 9

const double = multiply(2);
double(5);  // => 10
double(11); // => 22
Nach dem Login kopieren

如果 number2 参数不是 undefined,则该函数仅返回 number1 * number2

但是,如果 number2undefined,则意味着已经使用一个参数调用了 multiply() 函数。这时就要返回一个函数 doMultiply(),该函数稍后被调用时将执行实际的乘法运算。

doMultiply() 是闭包,因为它从 multiply() 作用域中得到了number1 变量。

总结

如果你答对了 5 个以上,说明对闭包掌握的很好。如果你答对了不到 5 个,则需要好好的复习一下了。

原文地址:https://dmitripavlutin.com/simple-explanation-of-javascript-closures/

转载地址:https://segmentfault.com/a/1190000039366748

更多编程相关知识,请访问:编程视频!!

Das obige ist der detaillierte Inhalt von7 Interviewfragen zu Schließungen in JavaScript, können Sie sie beantworten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage