函数声明中的函数声明,具有相同名称的javascript

时间:2013-09-12 20:45:57

标签: javascript

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

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

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

功能定义是怎么回事;在外面和内部宣布一次。这种方法的价值是什么?

4 个答案:

答案 0 :(得分:3)

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

由于JS函数作用域,内部函数只能在构造函数方法中使用。你可以从构造函数中调用内部测试(...),但似乎没有意义,因为推测args应该传递给构造函数。

可能的目的是:

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

test.prototype.someOtherMethod = function() {}

答案 1 :(得分:2)

首先要理解的是JavaScript中的函数创建了新的作用域 - 还没有块作用域。因此,在外部看不到在另一个函数内声明的每个变量或函数。

考虑到这一点:当您使用相同的外部名称定义内部函数时,您将失去通过名称递归调用外部函数的能力,因为内部函数将“接管”(或“影子“)那个名字。在这两个函数中,test将引用内部函数,而外部函数test 外部引用外部函数。

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

答案 2 :(得分:1)

这是范围。

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

在该函数中,您可以声明相同的名称,因为该函数在该范围内声明...更容易理解示例:

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
{
}

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

就像

class User
{
    private function Something()
    {
    }
}

最后

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

    // or

    return {
        Something: function(){}
    }
}

就像

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(){} ......答案是它只适用于那个实例......

答案 3 :(得分:0)

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