两种功能的区别? ("函数x"与"变量x =函数")

时间:2020-03-06 14:32:13  来源:igfitidea点击:
Possible Duplicate:

  JavaScript: var functionName = function() {} vs function functionName() {}

之间有什么区别?

function sum(x, y) {
  return x+y;
}

// and 

var sum = function (x, y) {
    return x+y;
}

为什么一个使用另一个?

解决方案

第一个是命名函数语句,第二个是将匿名函数表达式分配给变量。

我们可以在不需要调用函数语句的情况下立即将函数语句添加到其作用域,因此可以正常工作:

var y = sum(1, 2);

function sum(x, y) {
   return x + y;
}

但是函数表达式仅在执行代码时才分配给变量,因此这是行不通的:

// Error here because the function hasn't been assigned to sum yet.
var y = sum(1, 2);

var sum = function(x, y) {
   return x + y;
}

表达式形式的一个优点是,我们可以在不同的位置使用它为表达式分配不同的功能,以便我们可以更改该功能,或者在不同的条件下(例如,取决于所使用的浏览器)使用不同的功能。

命名函数语句的一个优点是,调试器将能够显示该名称。虽然,我们可以命名函数表达式:

var sum = function sum(x, y) {
   return x + y;
}

但是,这可能会造成混淆,因为这两个名称实际上在不同的范围内并且涉及不同的事物。

他们的意思完全相同。这只是语法糖。后者是IMO更加揭示了JavaScript的真正作用。即" sum"只是一个用函数对象初始化的变量,然后可以用其他东西代替:

$ js
js> function sum(x,y) { return x+y; }
js> sum(1,2);
3
js> sum=3
3
js> sum(1,2);
typein:4: TypeError: sum is not a function
js> sum
3

第一个称为命名函数,第二个称为匿名函数。

实际的关键区别在于何时可以使用求和函数。例如:-

var z = sum(2, 3);
function sum(x, y) {
    return x+y;
}

z被分配了5,而这是:

var z = sum(2, 3);
var sum = function(x, y) {
    return x+y;
}

将失败,因为在第一行执行时,尚未将变量sum分配给该函数。

在执行开始之前,已命名的函数将被解析并分配给它们的名称,这就是为什么可以在其定义之前的代码中使用已命名的函数的原因。

通过代码分配了功能的变量显然只能在执行通过分配后才能用作功能。

倾向于使用第一个有以下几个原因:

  • 名称" sum"显示在堆栈跟踪中,这使得在许多浏览器中的调试更加容易。
  • 可以在函数体内使用名称" sum",这使得递归函数更易于使用。
  • 函数声明在javascript中是"悬挂的",因此在第一种情况下,保证该函数被定义一次。
  • 分号插入的原因
var f = function (x) { return 4; }

(f)

将4分配给f

但是,有一些注意事项需要牢记。
不要做

var sum = function sum(x, y) { ... };

在IE 6上使用,因为它将导致创建两个函数对象。如果这样做特别令人困惑

var sum = function mySym(x, y) { ... };

根据标准
函数sum(x,y){...}
不能出现在if块或者循环体内,因此不同的解释器将对待

if (0) {
    function foo() { return 1; }
  } else {
    function foo() { return 2; }
  }
  return foo();

不一样。
在这种情况下,我们应该

var foo;
  if (0) {
    foo = function () { return 1; }
  } ...

区别是...

这是一个无名的功能

var sum = function (x, y) {
    return x+y;
}

因此,如果我们警报(求和);我们会收到"函数(x,y){return x + y;}"(无名)
虽然这是一个命名函数:

function sum(x, y) {
        return x+y;
}

如果我们警报(求和);现在我们得到"函数sum(x,y){return x + y;}"(名称为sum)

如果我们使用的是探查器,则具有命名函数会有所帮助,因为探查器可以告诉我们函数求和的执行时间...等等,而不是未知函数的执行时间...等等

这是另一个例子:
函数sayHello(name){alert('hello'+ name)}

现在,假设我们要修改按钮的onclick事件,例如说" hello world"

你不能写:

yourBtn.onclik = sayHello('world'),因为我们必须提供函数引用。

那么我们可以使用第二种形式:
yourBtn.onclick = function(){sayHello('workld'); }

ps:对不起,我的英语不好!

我们在此处张贴的两个代码段几乎可以出于所有目的以相同的方式运行。

但是,行为上的差异在于,使用第二个变体时,只能在代码中的该点之后调用该函数。

对于第一个变体,该函数可用于在声明该函数的位置上方运行的代码。

这是因为在第二个变体中,该函数在运行时分配给了变量foo。首先,在解析时将函数分配给该标识符foo。

更多技术信息

Javascript具有三种定义函数的方式。

  • 第一个示例是函数声明。这使用"功能"语句创建功能。该函数在解析时可用,并且可以在该范围内的任何位置调用。以后我们仍然可以将其存储在变量或者对象属性中。
  • 第二个片段显示了一个函数表达式。这涉及到使用"函数"运算符来创建函数-该运算符的结果可以存储在任何变量或者对象属性中。这种方式的功能表达是强大的。函数表达式通常称为"匿名函数",因为它不必具有名称,
  • 定义函数的第三种方法是" Function()"构造函数,该函数未在原始文章中显示。不建议使用它,因为它的工作方式与eval()相同,但存在问题。