4

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

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

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

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

4

4 回答 4

4

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

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

可能的意图是:

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

test.prototype.someOtherMethod = function() {}
于 2013-09-12T20:56:09.013 回答
3

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

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

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

于 2013-09-12T20:50:47.007 回答
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()
    {
    }
}

这一切都与范围有关。也许您有一个声明为函数的用户变量,并且您希望允许人们获取他的名字和姓氏,您可以将这些变量或函数声明为“公共”...但是如果您想知道他的饮食是否良好怎么办或坏的,你可能有一些复杂的函数来解决它,但你想知道一件事,好或坏..你可以将所有这些丑陋的函数设为私有,然后用一个公共函数显示结果。 ..

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!

你可能在想,你为什么不直接去 users[a].DoesUserLikeChips = function(){}...答案是它只适用于那个实例...

于 2013-09-12T20:56:16.127 回答
0

内部测试功能是private外部测试功能的功能。然后一个methodName函数被设置为public外部测试函数的函数。将内部函数命名为外部函数并没有什么特别之处。

于 2013-09-12T20:50:21.583 回答