Próbuję zrozumieć porządek wykonania w JavaScript. Dlaczego foo w ciele ma pierwszeństwo przed foo w głowie. Czy to nie jest foo w głowie, która jest pierwsza kompilowana?

<head>
  <meta charset="UTF-8">
  <title>Hello</title>

  <script type="text/javascript">
    function foo() {
      greeting = "hello from the head";
      alert(greeting);
    }
  </script>
</head>

<body>
  <div id="clickMe" onclick="foo()">Click me</div>
  <script>
    function foo() {
      greeting = "hello from the body";
      alert(greeting);
    }
  </script>
</body>

</html>
1
Marcin Kulik 3 czerwiec 2018, 07:49

4 odpowiedzi

Najlepsza odpowiedź

Późniejsze deklaracje funkcyjne nadpisują starsze deklaracje funkcji. Starsza funkcja może być nadal nazywana przed zadeklarowaniem nowszej funkcji :

<script type="text/javascript">
  function foo() {
    greeting = "hello from the head";
    alert(greeting);
  }
  foo();
</script>
<div id="clickMe" onclick="foo()">Click me</div>
<script>
  function foo() {
    greeting = "hello from the body";
    alert(greeting);
  }
</script>

Ale po uruchomieniu niższego znacznika skryptów nazwa funkcji jest ponownie przypisana. Może to zrobić więcej sensu, jeśli na to spojrzysz, a każda funkcja przypisanie window.foo:

<script type="text/javascript">
  window.foo = function foo() {
    greeting = "hello from the head";
    alert(greeting);
  }
</script>
<div id="clickMe" onclick="window.foo()">Click me</div>
<script>
  window.foo = function foo() {
    greeting = "hello from the body";
    alert(greeting);
  }
</script>
3
CertainPerformance 3 czerwiec 2018, 05:04

Nie jest inny niż deklarowanie tej samej funkcji dwukrotnie

function foo() {
  console.log("first");
}

function foo() {
  console.log("second");
}

foo();  // prints "second"

Który jest na pewnym poziomie nie inny niż to

let bar;
bar = 1;
bar = 2;

bar jest teraz 2.

Możesz tego uniknąć za pomocą innej składni

const foo = () => {
  console.log("first");
};

const foo = () => {
  console.log("second");
};

W takim przypadku otrzymasz błąd

Uncaught SyntaxError: Identifier 'foo' has already been declared

I wydaje się pracować nawet w poprzek skryptów

<script>
const foo = () => {
  console.log("first");
};
</script>
<script>
const foo = () => {
  console.log("second");
};
</script>
2
gman 3 czerwiec 2018, 05:21

To jest Call Shadowing.

JS Kompilator wciągniki działa, ponieważ znajdują się w skrypcie. Późniejsze nadpisują wcześniejsze spotkania o tej samej nazwie.

function foo() {
   console.log('Foo early');
}

function foo() {
   console.log('Foo late');
}

foo();    //Foo leate
0
Charlie 3 czerwiec 2018, 05:02

Zasadniczo jest to tylko dlatego, że ten w ciele jest ostatnią funkcją, którą czyta, więc po prostu przykleja się z nim.

Pamiętaj, że dokument HTML jest odczytywany od góry do dołu, więc jeśli masz dwa przypadki tej samej funkcji, rzeczywiście utrzyma go najbliżej końca dokumentu

0
IvanS95 3 czerwiec 2018, 05:28