[javascript] 내 JavaScript 함수 이름이 충돌하는 이유는 무엇입니까?

변수와 함수가 할당 된 함수가 이름이 충돌 할 때 어떤 일이 발생하는지보기 위해 다음 스크립트를 작성했습니다.

var f = function() {
    console.log("Me original.");
}

function f() {
    console.log("Me duplicate.");
}

f();

내가 얻는 출력은 “Me original”입니다. 다른 함수가 호출되지 않은 이유는 무엇입니까?

또한 원래 할당을로 변경 var f = new function() {하면 “Me original”이 표시되고 TypeError가 object is not a function. 누군가 설명해 주시겠습니까?



답변

함수 선언은 JavaScript에서 호이스트 (맨 위로 이동)됩니다. 구문 분석 순서는 올바르지 않지만 함수 선언이 호이스트되기 때문에 가지고있는 코드는 의미 상 다음과 동일합니다.

function f() {
    console.log("Me duplicate.");
}
var f = function() {
    console.log("Me original.");
}


f();

차례로 함수 이름을 제외하고는 다음과 같습니다.

var f = function() {
    console.log("Me duplicate.");
}
var f = function() {
    console.log("Me original.");
}


f();

차례로 가변 호이 스팅으로 인해 다음과 같습니다.

var f;
f = function() {
    console.log("Me duplicate.");
}
f = function() {
    console.log("Me original.");
}

f();

당신이 얻는 것을 설명하는 것은 함수를 재정의하고 있습니다. 보다 일반적으로 varJavaScript 에서는 여러 선언이 허용되며 이는 var x = 3; var x = 5완벽하게 합법적입니다. 새로운 ECMAScript 6 표준에서 let명령문은이를 금지합니다.

@kangax 의이 기사 는 자바 스크립트의 기능을 이해하는 데 환상적인 작업을 수행합니다.


답변

후속 질문에 아무도 답변하지 않은 것 같으면 여기서 답변하겠습니다. 일반적으로 후속 질문은 별도의 질문으로해야합니다.

이유를 물었습니다.

var f = new function() {
    console.log("Me original.");
}

function f() {
    console.log("Me duplicate.");
}

f();

“나의 원본”을 인쇄합니다. 그리고 오류.

여기서 일어나는 일은 new함수가 생성자로 사용되는 원인입니다. 따라서 이것은 다음과 같습니다.

function myConstructor() {
    console.log("Me original.");
}
var f = new myConstructor();

function f() {
    console.log("Me duplicate.");
}

f();

Benjamin이 설명한 기능 호이 스팅 덕분에 위의 내용은 본질적으로 다음과 같습니다.

var myConstructor = function() {
    console.log("Me original.");
};
var f = function() {
    console.log("Me duplicate.");
};

f = new myConstructor();

f();

이 표현 :

var f = new function() {
    console.log("Me original.");
}

f익명 함수를 생성자로 사용하여 새 객체를 생성하고에 할당합니다 . “나 오리지널.” 생성자가 실행되면 출력됩니다. 그러나 생성 된 객체는 그 자체가 함수가 아니므로 이것이 결국 실행될 때 :

f();

f함수가 아니기 때문에 오류가 발생 합니다.


답변

이것이 포인트 추가에 접근하는 잘못된 방법이라면 저를 용서하십시오. 나는 여기에 많이 가본 적이 없으며 건설적인 지시 및 / 또는 비판을 환영 할 것입니다.

Benjamin의 답변은 OP의 질문을 훌륭하게 다루지 만, 호이 스팅과 그 이상한 점에 대한 전체 둘러보기를 제공하는 하나의 조정을 추가하고 싶습니다.

다음과 같이를 호출하여 원래 코드를 시작하면 f:

f();

var f = function() {
   console.log("Me original.");
};

function f() {
   console.log("Me duplicate.");
}

f();

출력은 다음과 같습니다.

Me duplicate.
Me original.

그 이유는 그 varfunction진술이 약간 다른 방식으로 게양되기 때문입니다.

들어 선언 현재 범위의 *의 상단으로 이동하지만, 어떤 과제가 게양되지 않습니다. 선언 된 var의 값이가는 한 원래 할당 줄에 도달 할 때까지 정의되지 않습니다.var

들어 function , 선언 모두 정의가 게양된다. 구조에 사용 된 함수 표현식var f = function() {... 은 호이스트되지 않습니다.

따라서 호이 스팅 후 실행은 코드가 다음과 같습니다.

var f; // declares var f, but does not assign it.

// name and define function f, shadowing the variable
function f() {
  console.log("Me duplicate.");
}

// call the currently defined function f
f();

// assigns the result of a function expression to the var f,
// which shadows the hoisted function definition once past this point lexically
f = function() {
  console.log("Me original.");
}

// calls the function referenced by the var f
f();

* 모든 JavaScript 범위는 어휘 또는 기능, 범위이지만 그 시점에서 f 단어를 사용하면 혼란 스러울 것 같았습니다.


답변