我最近开始保持别人的JavaScript代码,我正在修复错误,添加功能,也试图更新代码并使其更加一致。

以前的开发人员使用了两种方式来宣布功能,我无法解决是否有原因。

兩種方式是:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

使用这两种不同的方法的原因是什么?每个方法的优点和缺点是什么?可以用一种方法做些什么,不能用另一种方法做些什么?


当前回答

我更喜欢将函数定义为变量:

let first = function(x){
   return x[0];
}

而不是:

function first(){
    ....
}

因为我可以在定义函数时使用表达式和装饰器,例如:

let safe = function(f){
  try {f()...}
}
let last = safe(function(x){return x[0]}).

此外,在 ES6 中,它更短:

 let last = x => x[0]
 ...........
 function last(x){
     return x[0];
 }
......

let last = safe(x => x[0]);

其他回答

我用我的代码中的变量方法出于一个非常具体的原因,其理论已经以抽象的方式被覆盖,但一个例子可以帮助一些像我这样的人,有有限的JavaScript专业知识。

有些品牌需要特定的功能,而有些则不。有时我需要添加新的功能来做新的品牌特定的事情.我很高兴更改共享编码,但我不想需要更改所有160套品牌文件。

使用变量合成,我可以在共享代码中宣言变量(基本上是函数指标),并分配一个三位一体函数,或设置为零。

当原始忍者物体被移除时,测试失败(第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));

关于表演:

新版本的V8引入了几个未来的优化,所以SpiderMonkey。

现在表达与声明之间几乎没有区别,功能表达似乎现在更快。

浏览器 62.0.3202

福克斯55

Chrome 加拿大 63.0.3225

此分類上一篇

匿名函数表达式似乎比名函数表达式表现更好。

此分類上一篇

此分類上一篇: Firefox Chrome Canary Chrome

二是定义函数的不同方式,区别在于浏览器如何解释并将其加载到执行背景中。

第一個案例是函數表達,只有當翻譯者達到這個代碼線時才會充電,因此,如果你這樣做,你會發現函數一不是函數的錯誤。

functionOne();
var functionOne = function() {
    // Some code
};

原因在于,在第一行中,没有值被分配到函数One,因此它是不定义的,我们试图称之为函数,因此我们得到一个错误。

在第二行中,我们将匿名函数的参考归分为函数One。

第二个案例是功能声明,在任何代码执行之前加载,所以如果你喜欢下一个,你不会得到任何错误,因为声明加载,在代码执行之前。

functionOne();
function functionOne() {
   // Some code
}

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

其次,可以结合两种风格:

var xyz = function abc(){};

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;

console.log(xyz === abc); // prints "true"

function abc(){};
console.log(abc.name); // prints "abc"

var abc = function(){};
console.log(abc.name); // prints ""

它的名字是空的 - 我们创建了一个匿名函数,并将其分配给一些变量。

使用合并风格的另一个好理由是使用一个简短的内部名称来引用自己,同时为外部用户提供一个长而不冲突的名称:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

在上面的例子中,我们可以用外部名称做同样的事情,但它会太不多(而且更慢)。

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

// We can call it here
abc(); // Works
return;
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

函数声明与函数表达是格雷格所证明的差异的真正原因。

有趣的事实:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

var abc = function(){};

我知道我定义了函数本地,当我定义了函数如

abc = function(){};

function abc(){};

它取决于背景,可能会让你猜测它实际上在哪里定义,特别是在 eval()的情况下 - 答案是: 它取决于浏览器。