我最近开始保持别人的JavaScript代码,我正在修复错误,添加功能,也试图更新代码并使其更加一致。
以前的开发人员使用了两种方式来宣布功能,我无法解决是否有原因。
兩種方式是:
var functionOne = function() {
// Some code
};
function functionTwo() {
// Some code
}
使用这两种不同的方法的原因是什么?每个方法的优点和缺点是什么?可以用一种方法做些什么,不能用另一种方法做些什么?
名称功能 vs. 匿名功能
第一函数合成是匿名函数表达式:
var functionOne = function() {
// do something...
};
但是,第二个是功能宣言:
function functionTwo () {
// do something...
}
兩者之間的主要區別是函數名稱,因為匿名函數沒有呼叫的名稱. 匿名函數是快速且容易宣告的,許多圖書館和工具往往鼓勵這種愚蠢的代碼風格. 然而,匿名函數有一些缺點:
可读性:匿名函数忽略了一个名称,可能会导致更少可读的代码。 解密: 匿名函数没有名称,可以使解密更困难。
名称函数表达式
為您的功能表達提供一個名稱,非常有效地解決所有這些缺點,並且沒有實際的缺點。
setTimeout(function timeHandler() { // <-- look, a name here!
console.log("I've waited 1 second");
}, 1000);
名称 IIFEs(即时启发功能表达)
(function IIFE(str) { // <-- look, always name IIFEs!
console.log(str); // "Hello!"
})('Hello!');
对于一个变量的函数,这个函数的名称,在这种情况下,不太常见,可能会导致混乱,在这种情况下,箭头函数可能是一个更好的选择。
在代码维护成本方面,所谓的功能更受欢迎:
无论它们在哪里被宣布(但仍然受到范围限制)。 更抵抗错误,如条件启动(你仍然可以过度排序,如果你愿意)。 代码变得更可读,通过分配地方功能分开的范围功能。 通常在范围内,功能先行,其次是局部功能的声明。
我怀疑更多关于名称功能的PROS正在追踪,而被列为名称功能的优势是匿名功能的缺点。
历史上,匿名函数出现,因为JavaScript作为语言无法列出名为函数的会员:
{
member:function() { /* How do I make "this.member" a named function? */
}
}
一个描述什么时候优先于第一种方法,而不是第二种方法,是当你需要避免超越一个函数的以前定义时。
与
if (condition){
function myfunction(){
// Some code
}
}
,这个定义的微功能将超越任何以前的定义,因为它将在时间段进行。
虽然
if (condition){
var myfunction = function (){
// Some code
}
}
正确的定义功能工作只有在条件满足时。
当原始忍者物体被移除时,测试失败(第13页)
function assert(predicate, message) { if(!predicate) { throw new Error(message); } }
var ninja = {
yell: function(n){
return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." );
var samurai = { yell: ninja.yell };
var ninja = null;
try {
samurai.yell(4);
} catch(e){
assert( false, "Uh, this isn't good! Where'd ninja.yell go?" );
}
function assert(predicate, message) { if(!predicate) { throw new Error(message); } }
var ninja = {
yell: function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" );
var samurai = { yell: ninja.yell };
var ninja = {};
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );
console.log(samurai.yell(4));
兩個函數之間的另一個區別是函數One 可以用作可持有多個函數的變量,而函數Two 持有某些代碼區塊,在呼叫時全部執行。
var functionOne = (function() {
return {
sayHello: function(){
console.log('say hello')
},
redirectPage:function(_url){
window.location.href = _url;
}
}
})();
您有一个选项,该函数将被称为. e.g 函数One.sayHello 或函数One. redirectPage. 如果您呼叫函数Two 那么整个代码块将被执行。