0

这里是 JS 新手,我最近一直在查看一些代码,这些代码使用了我不太熟悉的语法。这是一个示例,然后是我的问题:

function Group(args) {
  this.showItem = showItem;
  function showItem(args) {
    ...
  }
}
var group = new Group (args);

问题:

  1. 据我了解,它创建function Group然后实例化通过group = new Group本质上相当于定义一个类然后实例化该类的对象。那是对的吗?

  2. 关于 的属性(方法?)Group,上面调用的语法是showItem什么?为什么不把它定义为:

    this.showItem = function(args){...};
    

    将代码更改为上述代码会改变任何不同的行为吗?

  3. 如果您确实如上所述定义了它,那么该语法叫什么?

4

2 回答 2

3
  1. Group函数被用作构造函数;你的直觉基本上是正确的。

  2. 没有充分的理由使用匿名函数表达式this.showItem = function(args){...};,除非您想重用局部变量showItem

  3. 我不确定你的意思是哪种语法。是function(args){...}一个匿名函数表达式,并且this.showItem是指对象的一个​​成员this。综上所述,我想您可以将其称为“设置对象的成员函数”。

额外提示(也许您已经知道?):您可以showItem在定义之前使用它的原因是由于函数提升

编辑:

您似乎在询问函数表达式与函数声明以及命名函数与匿名函数。主要区别是:

  • 函数声明总是独立存在的。它们绝不是另一个操作的一部分,例如赋值。您的第一个示例使用函数声明function showItem(args) {...}。函数表达式在某些操作中用作表达式(例如,赋值、作为参数传递等)。您的第二种情况使用函数表达式。

  • 函数声明被提升到当前函数作用域的顶部,因此showItem在您的第一种情况下,当您在赋值操作中使用它时,定义并包含该函数。函数表达式没有被提升。

  • 函数声明总是被命名的。函数表达式可以命名或匿名。当使用名称定义函数时,该名称可作为name函数对象的属性访问。函数的名称是不可变的,并且独立于任何持有对该函数的引用的变量。此外,函数体内的代码可以通过函数名称将函数称为局部变量(这有时对命名函数表达式内的递归很有用)。

回顾:

  • 函数定义:function showItems(args){...};
  • 匿名函数表达式:this.showItems = function(args){...};
  • 命名函数表达式:this.showItems = function showItemsName(args){...};

在第一种情况下,有一个名为showItemsdefined 的局部变量,并且 的定义showItems被提升到顶部。后两种情况的区别在于第三种情况和第二种情况this.showItems.name将是“ ”。此外,将是第三个函数的函数体内的一个局部变量,它保存对函数对象的引用。showItemsNameundefinedshowItemsName

于 2012-12-31T17:36:58.803 回答
2
  1. Group函数用作构造函数。但是,这样做的方式有点低效。这段代码所做的是创建一个函数并将其附加到构造的对象上。他这样做可能是因为他想创建一个闭包(即使用仅存在于构造函数命名空间中的变量),但如果没有这个原因,最好这样做:

    function Group(args){}
    Group.prototype.showItem = function(args) {};
    

    这样,通过原型链showItem构造的所有对象都可以共享相同的功能。Group

  2. 与匿名函数相比,使用原始代码的好处是函数有一个名称——这对调试很有帮助,因为阅读充满匿名函数调用的回溯并不好玩!展开来说,使用关键字的事物有以下三种function

    • 函数声明在程序或函数的顶层(即,创建/拥有自己的命名空间的东西),您可以用名称声明函数。(该名称在整个程序中与函数对象保持一致,并将出现在回溯中。)这function showItem(args) {}在您的示例中。(请注意,这只是文件或函数顶层的函数声明。有一个非常相似的事情我将在最后讨论。)按照惯例,大多数人似乎在这些之后省略了分号。
    • 函数表达式当表达式的一部分(例如赋值、返回等)时,它是一个函数表达式。函数表达式的标识符部分是可选的,所以这些都是函数表达式:

      var myfunc1 = function(){};
      var myfunc2 = function MyFunctionName(){};
      

      第二种形式称为“命名函数表达式”。使用这种形式的最大好处是它MyFunctionName不再是一个匿名函数——这个名称将附加到函数上,并将显示在回溯中(例如)。然而,在 JScript (IE <= 8) 中存在一个非常严重的错误,导致使用这些问题。阅读我上面链接的文章以获取详细信息。

    • 最后,还有一种称为函数语句的通用扩展语法。这些看起来完全像函数声明,除了它们不是顶级的!例如:

      function() {
          function foo(){} // function declaration
          if (1) {
              function bar(){} // function STATEMENT--not standard JS!
          }
      }
      

      你不应该依赖这个扩展,而应该这样做:

      function() {
          var bar;
          if (1) {
              bar = function bar(){};
          }
      }
      
  3. this.showItem = function(){}将被称为“赋值中的函数表达式”,而原始代码只是使用“函数声明”。

于 2012-12-31T18:10:07.113 回答