如何在Javascript中覆盖函数提升?

时间:2015-09-19 08:36:56

标签: javascript debugging

不是函数abc()hoisted? 假设var abcfunction abc都被悬挂,哪个优先?

var abc = 10;
console.log(abc);

abc();

function abc(){
    console.log("abc");
}

为什么以下代码显示错误“abc不是函数”?

2 个答案:

答案 0 :(得分:3)

这相当于写作

// hoisted stuff
var abc;
function abc(){
    console.log("abc");
}
// end hoisted stuff
// your code is now
abc = 10; // abc now no longer a function
console.log(abc);
abc();

答案 1 :(得分:1)

这是因为Javascript中的功能提升功能。 You can read more about it here。它基本上意味着如果你在代码中定义一个函数,Javascript在解析代码时会发现它,并假设它在范围内被定义。所以这段代码:

abc();

function abc(){
    console.log("abc");
}

就像你写道:

一样
function abc(){
    console.log("abc");
}

abc();

但是您通过明确定义abc来覆盖该功能。 因此,假设abc是您定义的变量,它将被执行。 如果在定义函数后调用abc(),它甚至无法工作:

var abc = 10;
console.log(abc);

function abc(){
    console.log("abc");
}

abc(); // still an error because abc is still considered a var
console.log(abc); //prints 10

通过定义一个与函数名称相同的变量,您基本上将其隐藏起来。要解决这个问题,您可以给它们不同的名称或使用函数表达式(就像为变量赋值并且不进行提升一样):

var abc = 10;
console.log(abc); // prints 10

abc = function abc() { // you are assigning a new value to abc
    console.log("abc");
}

abc(); // prints 'abc'

请记住,当您使用函数表达式时,函数名称只能在函数体内访问。

var a = function b() { console.log('b')}
b() // Uncaught ReferenceError: b is not defined
a() // prints 'b'

在这种情况下,函数名称可以在函数体内用于递归调用:

function b(x) { return x > 2 ? x * b(x - 1) : 1 }
b(4); // returns 12