Javascript:向我解释这个语法

时间:2012-12-31 17:30:40

标签: javascript syntax

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. 如果您按上述方式定义了它,那么该语法是什么?

2 个答案:

答案 0 :(得分:3)

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

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

  3. 我不确定你的意思是什么。 function(args){...}是匿名函数表达式,this.showItem是指对象this的成员。综合考虑,我想你可以称之为“设置对象的成员函数”。

  4. 奖金提示(您可能已经知道了?):您可以在showItem定义之前使用function showItem(args) {...}的原因是function hoisting

    修改

    您似乎在询问function expressions versus function declarations以及命名与匿名函数。主要区别是:

    • 功能声明始终独立存在。它们永远不属于另一种操作,例如分配。您的第一个示例使用函数声明showItem。函数表达式在某些操作中用作表达式(例如,赋值,作为参数传递等)。第二种情况使用函数表达式。

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

    • 函数声明始终以命名方式命名。函数表达式可以是命名的或匿名的。使用名称定义函数时,可以将该名称作为函数对象的function showItems(args){...};属性进行访问。函数的名称是不可变的,并且独立于任何包含对函数的引用的变量。此外,函数体内的代码可以通过名称将函数引用为局部变量(有时对命名函数表达式中的递归有用)。

    要审核:

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

    在第一种情况下,定义了一个名为showItems的局部变量,this.showItems.name的定义被提升到顶部。后两种情况之间的区别在于showItemsName对于第三种情况为“undefined”,对于第二种情况为showItemsName。此外,{{1}}将是第三个函数的函数体内的局部变量,它保存对函数对象的引用。

答案 1 :(得分:2)

  1. Group函数用作构造函数。但是,这样做的方式效率有点低。这段代码正在做的是创建一个 new 函数并将其附加到构造对象。他可能正在这样做,因为他想创建一个闭包(即使用仅存在于构造函数的命名空间中的变量),但没有这个原因,最好这样做:

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

    这样,showItem通过原型链在Group构建的所有对象之间共享相同的function showItem(args) {}函数。

  2. 使用原始代码与匿名函数的好处是函数有一个名称 - 这对调试很有帮助,因为读取一个充满匿名函数调用的回溯并不好玩!要展开,有three types of things that use the function keyword

    • 函数声明当在程序或函数的顶层(即创建/拥有自己的命名空间的东西)时,您可以声明一个函数一个名字。 (该名称在整个程序中与函数对象保持一致,并将显示在回溯中。)在您的示例中,这是var myfunc1 = function(){}; var myfunc2 = function MyFunctionName(){}; 。 (请注意,这只是一个函数声明位于文件或函数的顶层。这是一个非常类似的东西,我会持续。)按照惯例,大多数人似乎在这些之后省略分号。
    • 函数表达式当表达式的一部分(如赋值,返回等)时,它是一个函数表达式。函数表达式的标识符部分是可选的,因此它们都是函数表达式:

      MyFunctionName

      第二种形式称为“命名函数表达式”。使用此表单的最大好处是function() { function foo(){} // function declaration if (1) { function bar(){} // function STATEMENT--not standard JS! } } 不再是匿名函数 - 此名称将附加到函数中,并将显示在回溯中(例如)。然而,JScript中存在一个非常严重的错误(IE< = 8),这使得使用这些有问题。阅读上面链接的文章了解详情。

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

      function() {
          var bar;
          if (1) {
              bar = function bar(){};
          }
      }
      

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

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