我刚刚在javascript中看到了这种模式:
var test = function () {
function test(args) {
this.properties = args || {}; //etc
}
}
test.prototype.methodName = function (){} //...etc
功能定义是怎么回事;在外面和内部宣布一次。这种方法的价值是什么?
答案 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
函数。将内部函数命名为外部函数没有特殊之处。