2013-03-22 43 views
4

我正在寻找使用对象创建命名空间和自我执行匿名函数。哪一个被认为是更好的选择?jQuery命名空间使用对象和自我执行匿名函数

使用对象,给出一个唯一的名称'myAppName'足以防止碰撞?

var myAppName = { 
    val1: "abc", 
    val2: "xyz", 
    myFunc1: function() { 
     return this.val2; 
    } 
} 

console.log(myAppName.val1); // abc 
console.log(myAppName.myFunc1()); // xyz 

使用自执行的匿名函数:

(function() { 
val1 = "abc"; 
    var val2 = "xyz"; 

    myFunc1 = function() { 
     return val1; 
    } 

    var myFunc2 = function() { 
     return val2; 
    } 
})(); 

console.log(val1); // abc 
console.log(myFunc1()); // abc 
console.log(myFunc2()); // xyz 

在自执行功能上面的代码,它们似乎都执行。在变量和函数名之前是否有使用和不使用var的含义?我不太明白。有没有办法将变量和函数设置为私有和公共的?或者是自执行功能中的所有内容都是私有的?

如果我在自我执行功能之前使用'var'会发生什么?

var myAppName = (function() { 
val1 = "abc"; 
    var val2 = "xyz"; 

    myFunc1 = function() { 
     return val1; 
    } 

    var myFunc2 = function() { 
     return val2; 
    } 
})(); 
+1

在你的第二个代码块中,调用'console.log(myFunc2());'不会显示'xyx'。相反,它会抛出'ReferenceError:myFunc2未定义'。这是因为'myFunc2'对匿名函数是本地的。 – 2013-03-23 04:04:02

+1

在你的第三个代码块中,'myAppName'将会是'undefined',因为你没有从函数返回任何东西。 – 2013-03-23 04:05:11

回答

4

我的第一个答案试图解决您的原始问题,并展示如何设置一个名称空间。我决定添加第二个答案来解决评论中提出的问题,以回答我的第一个问题。

全局变量实际上是window对象的属性。如果在函数外部使用var,则正在定义全局变量。如果在函数内部使用var,那么您正在定义一个局部变量。如果参考变量someValue而不用var进行声明,则与参考window.someValue相同。

以下代码显示了设置全局变量的不同方式,以及定义局部变量的一种方法。

window.global1 = 'abc'; 
global2 = 'def'; 
var global3 = "ghi"; 

(function() { 
    window.global4 = 'jkl'; 
    global5 = 'mno'; 
    var local1 = 'xyz'; 
})(); 

console.log(global1); // 'abc' 
console.log(global2); // 'def' 
console.log(global3); // 'ghi' 
console.log(global4); // 'jkl' 
console.log(global5); // 'mno' 
console.log(local1); // ReferenceError: local1 is not defined 

一般来说,您想限制设置全局变量(至少在创建JavaScript库时)。命名空间基本上只是一个全局变量。当你将所有其他东西放在该名称空间下时,只添加了一个全局变量。

我认为这也是避免设置上述global2global5等全局变量的最佳做法。相反,您应该使用函数的var oustide(如global3)或在window对象上设置属性(如global1global4)。

从我的其他答案借用的代码示例中,我们可以创建这样一个命名空间:

var myApp = (function() { 
    var privateValue = 'abc'; // Don't forget "var" here. 

    function privateFunction() { 
     return privateValue; 
    } 

    return { 
     publicValue: 'xyz', 

     publicFunction: function() { 
      return privateFunction(); 
     } 
    } 
})(); 

我们可以通过执行以下操作可以达到同样的,但我认为这是不好的风格:

(function() { 
    var privateValue = 'abc'; // Don't forget "var" here. 

    function privateFunction() { 
     return privateValue; 
    } 

    myApp = { 
     publicValue: 'xyz', 

     publicFunction: function() { 
      return privateFunction(); 
     } 
    } 
})(); 

在这两种情况下,我们都设置了myApp全局变量,但我认为前者要比后者明显得多。

只是要清楚,在这两种情况下,我们将解决公共变量作为myApp.publicValue和呼叫使用myApp.publicFunction()公共功能和匿名函数之外,我们将无法引用privateValueprivateFunction

3

将所有的代码放在一个命名空间下,肯定会有助于避免名称冲突。如果确实有碰撞,更改代码以处理它会容易得多。

如果一切都需要公开,您的第一个代码示例没有问题。如果你想要一些东西是私有的,使用匿名,立即执行的功能,如:

var myApp = (function() { 
    var privateValue = 'abc'; // Don't forget "var" here. 

    function privateFunction() { 
     return privateValue; 
    } 

    return { 
     publicValue: 'xyz', 

     publicFunction: function() { 
      return privateFunction(); 
     } 
    } 
})(); 

通知匿名函数如何返回包含公共变量和函数的对象。如果你没有在“privateValue”之前加上“var”,那么你没有定义一个局部变量; (这是真正的“窗口”对象的属性),取而代之的是,你引用一个全局变量

如果您正在使用jQuery,我提出以下建议:

(function(window, $, undefined) { 

    var myApp = (function() { 
     var privateValue = 'abc'; // Don't forget "var" here. 

     function privateFunction() { 
      return privateValue; 
     } 

     return { 
      publicValue: 'xyz', 

      publicFunction: function() { 
       return privateFunction(); 
      } 
     } 
    })(); 

    // Put myApp in the global scope. 
    window.myApp = myApp; 

})(window, jQuery); 

这样一来,你是安全的使用$()而不是jQuery()。您也可以安全地将undefined视为一个常数。您还可以更轻松地处理某人已经覆盖窗口对象的情况。

+0

谢谢。在执行'(function(){'和'var myApp =(function(){'?)之间有区别吗?或者它是同样的事情?我想在前者中,我访问变量或函数:'console。 log(val1);'和后者是这样的:'console.log(myApp.val1);'。是吗?除此之外的任何其他差异? – user1448031 2013-03-22 23:45:16

+0

@ user1448031 - 我添加了另一个答案,希望能回答你的问题。 – 2013-03-23 04:07:55

相关问题