2014-10-10 44 views
0

我有两个函数命名初始化的Javascript:在函数声明函数表达式

一个使用函数声明和其他使用函数表达式声明,如下所示:

function init() { 
    alert ('init 1'); 
} 

var init = function(){ 
    alert('init 2'); 
} 

init(); 

当我调用init函数它提醒初始化2.

Demo

我questio n是:

1-为什么javascript不会抛出错误,因为这两个函数具有相同的名称。

2-如何调用第一个函数?

+0

第二个init不是一个函数,第一个是通过一个简单的语句调用的,例如'init();'http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-函数名称 – VPK 2014-10-10 11:56:06

+0

init();不是第一个调用第二个方法,请检查我的小提琴。 – 2014-10-10 11:57:39

回答

3

为什么javascript不会抛出错误,因为两个函数都有相同的名称。

它们没有相同的名称。第二个是包含匿名函数的变量init。第一个是名为init的函数。

您可以通过执行两个以下测试:

console.log(init.name); 

你会看到,第一确实有一个名字init,而第二个没有名字。

我该如何调用第一个函数?

在这个例子中,在第二个变量中使用init后,第一个不能被调用。除非你有另外一个引用,像这样:

function init() { 
     alert ('init 1'); 
} 
var original = init; 
+1

虽然学生们可能希望在命名函数和赋予命名变量的匿名函数之间作出区分,并且两者之间确实存在差异,但在日常实践中,简单的事实就是两种名称共享本地作用域,并且不能同时存在同一个名称。 OP的问题仅仅是为什么JS没有像其他语言那样报告这个错误(回答:因为它没有),并且一旦我在本地范围内覆盖了一个名称,我可以返回旧版本(答案:你不能)。 – 2014-10-10 12:08:28

+0

*它们不具有相同的名称*实际上,这是** NOT ** JS不会抛出错误的原因。如果是这样的话,可能会认为'function foo(){}函数foo(){}'或'var x = 1; var x = 1; ** **会抛出一个错误,但他们也不会。 JS不抛出错误的原因是,好的,** JS在变量或函数重定义或重新分配的情况下不会抛出错误**。无论是变量还是函数都是无关紧要的。 – 2014-10-10 12:18:55

0

Javascript获取函数的最后定义。 您可以将其重命名为唯一的,也可以使用“严格”来使其具有本地功能。

function functions(){ 
    "use strict" 
    var init = function(){ 
     console.log("b"); 
    }; 

    return { 
     start : init 
    } 
}; 

var fn = new functions(); 
fn.start(); 
+0

没有得到关于“严格使用';使其成为本地函数”的部分。 – 2014-10-10 12:02:04

2

没有什么之间你正在做什么和

var i = 1; 
var i = 2; 

没有,JS不会抛出一个错误,也没有,一旦你重新定义i你不能老根本不同价值回归。

在ES6和一些现代的浏览器,你可以说

const i = 1; 

,然后如果它重新定义了引擎会抱怨。

+0

所以简单地说,变量init就是重写第一个init函数? – 2014-10-10 12:07:58

+0

是的,虽然不是“覆盖”,我可能会说“覆盖”或“重新定义”或“重新分配”。 – 2014-10-10 12:10:13

2

JavaScript中的声明被挂起。函数声明是声明的一种类型。因此,你的程序是等价于:

var init = function init() { 
 
    alert("init 1"); 
 
}; 
 

 
var init = function() { 
 
    alert("init 2"); 
 
}; 
 

 
init();

如果你的第二个定义之前调用init那么它会提醒init 1

function init() { 
 
    alert("init 1"); 
 
} 
 

 
init(); 
 

 
var init = function() { 
 
    alert("init 2"); 
 
};

由于吊装你甚至可以校准升init它出现在程序之前:

init(); 
 

 
function init() { 
 
    alert("init 1"); 
 
} 
 

 
var init = function() { 
 
    alert("init 2"); 
 
};

只记得比他们在程序中出现什么样的顺序不管,函数的声明永远是第一位:

init(); 
 

 
var init = function() { 
 
    alert("init 2"); 
 
}; 
 

 
function init() { 
 
    alert("init 1"); 
 
}

Hop e有帮助。

+0

悬挂的绝佳摘要,但它与OP的问题有什么关系? – 2014-10-10 12:03:32

+1

我知道关于提升,我想知道我的第一个函数会发生什么,它是否被第二个函数覆盖或者它是否仍然存在于全局名称空间中? – 2014-10-10 12:10:37

0

您可以种命名空间:

var p1 = { 
 
    init: function() { 
 
    alert('init 1'); 
 
    } 
 
}; 
 

 
var p2 = { 
 
    init: function() { 
 
    alert('init 2'); 
 
    } 
 
}; 
 

 
var init = function() { 
 
    p1.init(); 
 
    p2.init(); 
 
}; 
 

 
init();
Running ...

0

这工作:

function init() { 
    alert ('init 1'); 
} 

var init = (function(oldInit) { return function() { 
    oldInit(); // Call the first definition this way 
    alert('init 2'); 
}; })(init); 

init(); 

关键是要有第二的init()还记得以前的初始化。 Javascript不会抛出错误,因为重新定义函数通常很有用。