我刚刚在 javascript 中看到了这种模式:
var test = function () {
function test(args) {
this.properties = args || {}; //etc
}
}
test.prototype.methodName = function (){} //...etc
函数定义发生了什么;一次在外面,一次在里面。这种方法的价值是什么?
我刚刚在 javascript 中看到了这种模式:
var test = function () {
function test(args) {
this.properties = args || {}; //etc
}
}
test.prototype.methodName = function (){} //...etc
函数定义发生了什么;一次在外面,一次在里面。这种方法的价值是什么?
它很奇怪。“外部”函数充当构造函数,您可以使用它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() {}
这里首先要理解的是 JavaScript 中的函数创建了新的作用域——还没有块作用域。因此,在另一个函数中声明的每个变量或函数对外部都是不可见的。
考虑到这一点:当您使用与外部函数相同的名称定义内部函数时,您将失去按名称从自身递归调用外部函数的能力,因为内部函数将“接管”(或“影子”)那个名字。在这两个函数内部,test
都会引用内部函数,而外部函数外部test
总是引用外部函数。
由于在您正在修改的函数定义之后test.prototype
,我们可以假设test
(外部的)将用作构造函数。在这种情况下,innertest
可以看作是构造函数的“私有”方法,只能从构造函数内部调用。有关在函数中使用这种面向对象的函数的详细示例,请参阅James T 的回答。
这是范围。
当您将变量定义为函数时,它会创建函数范围。
在该函数内部,您可以声明相同的名称,因为该函数是在该范围内声明的......举一个更容易理解的例子:
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(){}...答案是它只适用于那个实例...
内部测试功能是private
外部测试功能的功能。然后一个methodName
函数被设置为public
外部测试函数的函数。将内部函数命名为外部函数并没有什么特别之处。