问:答:js中varfunctionName=function(){}和functionfunct。。。
stackOverflow中看到了很久以前问的⼀个关于函数声明的问题,问题对函数剖析的特别深。这⾥翻译了⼀下组织成⼀篇⼩博⽂,加深⼀下对这两种声明⽅式的印象。虽是⽼调重弹,但是只要能帮助理解问题,不管多⽼,都是好的。
js中有两种声明函数的⽅法,分别为:
var functionOne = function() {
// Some code
};
function functionTwo() {
// Some code
}
为什么会有两种不同的⽅法?每个⽅法的优点和缺点分别是什么?有什么情况是⼀种⽅法能完成⽽另外
⼀种⽅法不能完成的吗?
by @
不同点在于functionOne只会在到达赋值的那⼀⾏才会被真正定义,⽽functionTwo会在包含它的函数或script脚本执⾏的时候马上被定义。例如:
1 <script>
2// Error undefined
3 functionOne();
4
5var functionOne = function() {
6 };
7
8// No error
9 functionOne();
10 </script>
11
12 <script>
13// No error
14 functionTwo();
15
16function functionTwo() {
17 }
18 </script>
这也意味着你不能在条件语句中使⽤第⼆种⽅法定义函数:
<script>
if (test) {
// Error or misbehavior
function functionThree() { doSomething(); }
}
</script>
上⾯的例⼦⽆论test的值是真是假,实际上已经定义了functionThree函数。
by @
另外,也可以结合以上两种函数定义⽅法:
var xyz = function abc(){};
xyz 函数将会正常定义。⽽ abc 函数不会在浏览器中定义(除了IE浏览器),但是在其函数体内可见:
var xyz = function abc(){
// xyz is visible here
// abc is visible here
}
// xyz is visible here
// abc is undefined here
如果你想在所有浏览器中使⽤函数别名,可以使⽤这种声明⽅式:
function abc(){};
var xyz = abc;
这种情况下 xyz 和 abc 是同⼀个函数对象的别名:
console.log(xyz === abc); // prints "true"
使⽤第⼆种⽅式进⾏函数定义的⼀个说服性理由是,该函数对象有"name"属性(IE不⽀持)。当你定义⼀个类似下⾯的函数:
function abc(){};
console.log(abc.name); // prints "abc"
函数的name属性会被⾃动分配。但是当你以下⾯的⽅式定义函数:
var abc = function(){};
console.log(abc.name); // prints ""
它的name属性为空——这⾥创建了⼀个匿名函数,并将它赋值给其他变量。
推荐使⽤第⼆种函数定义⽅法的另⼀个理由是,可以⽤⼀个简短的内部名称来引⽤函数本⾝,同时为外部⽤户提供⼀个长的⽆冲突的别名:
// Assume al.scoped is {}
al.scoped.name = function shortcut(n){
// Let it call itself recursively: 循环调⽤其本⾝
shortcut(n - 1);
// ...
// Let is pass itself as a callback: 作为回调函数来传参
someFunction(shortcut);
// ...
}
在上⾯的例⼦中我们可以⽤⼀个外部声明来做和原函数相同的事,但是这样做不⽅便(同时太慢)。
(引⽤函数本⾝的其他⽅法是使⽤arguments.callee,这种⽅法⽐较常见<;不知道这么翻译对不对>,并且在严格模式中不⽀持)。
实际上,javaScript对两种函数声明⽅法对待不同。这是⼀个函数声明:
function abc(){}
这⾥的abc在⽬前的范围中是处处都有定义的:
// We can call it here
abc(); // Works
// Yet, it is defined down there.
function abc(){}
// We can call it again
abc(); // Works
同样,它也会透过⼀个return语句被提前定义:
// We can call it here
abc(); // Works
return;
js arguments
function abc(){}
另外⼀个函数表达式:
var xyz = function(){};
这⾥的xyz在声明⾏被定义:
// We can't call it here
xyz(); // UNDEFINED
// Now it is defined
xyz = function(){}
// We can call it here
xyz(); // works
对函数(function)表达式和函数(Function)声明,我更倾向 "函数表达式" 声明(第⼀种⽅式),因为这种⽅式我可以控制可见性。当我定义这样⼀个函数:var abc = function(){};
我知道我定义了⼀个局部函数。当我定义⼀个这样的函数:
abc = function(){};
我知道我定义了⼀个全局函数,并且我没有在作⽤域链的任何位置定义abc<;不太清楚如何翻译>。然⽽像下⾯的定义⽅式:
function abc(){};
取决于上下⽂并且可能会让你猜测该函数真实定义的地⽅,特别是在使⽤eval()⽅法的时候——答案是:依赖于其所在的浏览器。
问题地址:
翻译的不好,请勿拍!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论