同名javascript函数声明中的函数声明

同名javascript函数声明中的函数声明,javascript,Javascript,我刚刚在javascript中看到了这种模式: var test = function () { function test(args) { this.properties = args || {}; //etc } } test.prototype.methodName = function (){} //...etc 函数定义发生了什么变化;一次在外面,一次在里面。这种方法的价值是什么?内部测试函数是外部测试函数的私有函数。然后将methodName函数设置

我刚刚在javascript中看到了这种模式:

var test = function () {
    function test(args) {
       this.properties = args || {}; //etc
    }
}

test.prototype.methodName = function (){} //...etc

函数定义发生了什么变化;一次在外面,一次在里面。这种方法的价值是什么?

内部测试函数是外部测试函数的
私有
函数。然后将
methodName
函数设置为外部测试函数的
public
函数。将内部函数命名为外部函数没有什么特别之处。

这里首先要了解的是,JavaScript中的函数会创建新的作用域——目前还没有块作用域。因此,在另一个函数中声明的每个变量或函数对外不可见

记住这一点:当您使用与外部函数相同的名称定义内部函数时,您将失去从外部函数本身按名称递归调用外部函数的能力,因为内部函数将“接管”(或“影子”)该名称。在两个功能内部,
test
将指内部功能,而在外部功能外部,
test
始终指外部功能

因为在函数定义之后,您正在修改
test.prototype
,所以我们可以假设
test
(外部的)将用作构造函数。在这种情况下,内部
测试可以看作是构造函数的“私有”方法,只能从构造函数内部调用。有关函数中函数的面向对象使用的详细示例,请参阅。

这是范围

将变量定义为函数时,它会创建函数范围

在该函数内,您可以声明相同的名称,因为该函数是在该范围内声明的。。。举一个更容易理解的例子:

var User = function()
{
    function PrivateToScope()
    {
        // A Function Only Accessible Inside This Function
        alert( "private" );
    }

    return 
    {
        PublicToScope: function()
        {
            // A Function Accessible From Outside This Function
            alert( "public" );
        } 
    }
}

var James = new User();
James.PublicToScope(); // Will alert "public"
James.PrivateToScope(); // Will fail to do anything
因此,为了解释答案,用户设置了作用域,因为您使用相同的名称声明了上述函数,所以这并不重要


人们不喜欢我这样说,但你可以把这种方法想象成是其他语言中的一个类

var User = function()
{
}
就像

class User
{
}
class User
{
    private function Something()
    {
    }
}
class User
{
    public function Something()
    {
    }
}

就像

class User
{
}
class User
{
    private function Something()
    {
    }
}
class User
{
    public function Something()
    {
    }
}

最后

var User = function()
{
    this.Something = function()
    {
    }

    // or

    return {
        Something: function(){}
    }
}
就像

class User
{
}
class User
{
    private function Something()
    {
    }
}
class User
{
    public function Something()
    {
    }
}
这都是关于作用域的。也许您将一个用户变量声明为函数,并且您希望允许人们获取他的名字和姓氏,您可以将这些变量或函数声明为“public”。。。但是如果你想知道他的饮食是好是坏,你可能有一些复杂的功能来解决它,但你想知道一件事,好还是坏。。你可以让所有这些做丑陋事情的函数都私有化,然后用一个公共函数显示结果

var User = function()
{
    function CalculateDiet()
    {
        // Lots of scary diet calculating stuff comes out with the result
        return result;
    }

    return
    {
        FirstName: "James",
        LastName: "Poop",
        StandardOfDiet: function()
        {
            return CalculateDiet();
        }
    }
}

var MyUser = new User();
alert( MyUser.FirstName );
alert( MyUser.StandardOfDiet() );
你为什么在意?

量化它既简单又困难,但这里有一些好的

  • 它很整洁
  • 如果你把一堆巧克力放在桌子上,它们都会被吃掉。。但其中一个是给你的,人们都很贪婪。。。只在桌子上布置你想让他们吃的东西,他们不能贪心然后一不小心吃了你的巧克力
  • 它为您设置面向类的编程
  • 很清楚程序员打算用代码做什么
  • 内存使用率(我确信在不需要公开的情况下声明更多函数会有开销
最后,另一方面,您的测试附带了一个原型,因此让我们为我们的用户示例执行此操作。假设我们有一组用户:

var users = [
    new User(),
    new User()
];
我们可以对其进行迭代,获得其所有常用属性和方法:

for( a in users )
{
    alert( users[ a ].FirstName );
}
但假设我们的应用程序中发生了一些事情……用户单击一个按钮,询问每个用户是否喜欢炸鱼和薯条,我们现在需要为用户提供一个新方法……我们可以为该变量“user”的所有迭代创建一个新方法的原型我们创建了…我们可以提前声明它,但这样我们会浪费内存,可能会让未来的程序员感到困惑,因为它的存在是基于一些非常具体的东西:

// user clicks button and runs this code
User.protoype.DoesUserLikeChips = function(){
    // put some code in here that somehow makes this example make sense :)
}
现在,对于阵列中的每个用户,您都可以调用此新方法…新功能babehhh

您可能会想,为什么不直接访问用户[a].DoesUserLikeChips=function(){}…答案是它只应用于一个实例…

这很奇怪。“外部”函数充当构造函数,您可以使用
var myTest=new test();
创建一个新的
测试

由于JS函数的作用域,内部函数只能在构造函数方法中使用。您可以从构造函数中调用内部测试(…),但它似乎毫无意义,因为应该将
args
传递给构造函数

可能的目的是:

var test = function(args) {
    this.properties = args || {}; // you may want to actually parse each arg here
}

test.prototype.someOtherMethod = function() {}

内部测试函数和外部测试函数不一样:它们不是在同一个范围内定义的。请记住javascript是函数范围的,这样很容易判断在这种情况下发生了什么。你确定这就是你看到的模式吗?是否省略了什么?绝对没有指向第一个块嵌套测试函数只能在包装函数内部访问,并且没有调用嵌套测试函数的内容。请不要在多个堆栈交换站点上发布完全相同的问题。我们将程序员版本带到这里,并将其与此版本合并,没有理由在不同的站点上有相同问题的答案在将来,如果你想把你的问题迁移到另一个网站,只需标记为关注适度,并要求主持人为你移动它。