Javascript中的常量变量

时间:2011-06-20 16:10:43

标签: javascript

我正在尝试使用一些const全局变量,我可以在javascript中使用这些变量,然后我推出了这个代码并从SO中提到的一些答案中获取。但似乎我在某处无法发现一点点错误。有人可以帮我这个吗?

in testQuery.js

(function (window, undefined) {

    var testQuery = function(obj) {
        if (!(this instanceof testQuery)) {
            return new testQuery(obj);
        }
    }

    var MYGLOBALS = function() {
        var globals = {
            foo : "bar",
            batz : "blah"           
        }

        return {
            getValue : function(s) {
                return globals[s];
            }
        }
    }();

    window.testQuery = testQuery;

}) (window);

在html javascript标签中我有这行代码。

在testQuery.html文件中

<html>
  <head>
    <script src="testQuery.js"></script>
    <script>

       function onClick() {

             alert(MYGLOBALS.getValue("foo"));
       }

    </script>
  </head>

  <body>

      <input type="button" onclick="onClick()">

  </body>

</html>

2 个答案:

答案 0 :(得分:3)

变量MYGLOBALS是您的作用域函数的本地函数(没有名称的最外层函数),因此只能从该函数中访问它。

我不确定你的意思是“......在html javascript代码中......”但是如果您引用的alert超出该范围函数,MYGLOBALS就会出局适用范围。


更新:关于JavaScript范围的事情是它比人们想象的更简单 。使用var声明的变量是范围内的私有(函数或全局; JavaScript没有块级范围,所以只有{}没有这样做),它们被声明,并且子范围是该范围(例如,在其中声明或定义的函数)。范围完全是 lexical - 也就是说,它是您在源代码中看到的,而不是由其他运行时结构决定的。它们不会弹出该范围,除非您看到代码明确地发生了这种情况,就像您的window.testQuery = testQuery;行一样,它明确地使testQuery成为window上的属性,因此是全局变量。 (即便如此,并不是变量已经超出了范围,只是你已经创建了一个 new 属性,引用了更广泛可访问的相同内容。)


更新2 :重新发表评论

  

实际上我要做的是创建一些类似你在用其他语言编程时会看到的东西,其中会有一个最终的静态整数,你可以把它放到你调用的函数的参数字段中。有没有更好的方法呢?例如,在visual basic中它的类似me.background = Color.YELLOW。我想要的是有一个静态变量,它代表黄色。

JavaScript没有用户定义的常量,也没有枚举。 (更新:这两件事情都可能因ES6而改变。)你所做的是定义一个具有属性的对象,例如:

var COLORS = {
    RED: "#FF0000",
    BLUE: "#0000FF",
    // ...
    GREEN: "#00FF00"
};

那些不是常量,没有任何东西可以让任何人分配给COLORS.RED,除非你告诉他们不要。

(更新:在ES5中,我们可以使用Object.defineProperties使这些属性保持不变,如下所示:

var COLORS = Object.defineProperties({}, {
    RED:   {value: "#FF0000"},
    BLUE:  {value: "#0000FF"},
    // ...
    GREEN: {value: "#00FF00"}
});

当您以这种方式定义属性时,默认情况下它不可写。)

对于你正在做的事情,你可能想要模块模式,你有一个全局符号,其值是一个对象,其他一切都是该对象的属性:

(function() {
    var mod;

    // Create the global, and also give ourselves a convenient alias for it (`mod`)
    window.MyModule = mod = {};

    // Colors
    mod.COLORS = {
        RED: "#FF0000",
        BLUE: "#0000FF",
        // ...
        GREEN: "#00FF00"
    };

    mod.testQuery = MyModule_testQuery;
    function MyModule_testQuery() {
        // Do something
    }

})();

alert(MyModule.COLORS.RED); // #FF0000
MyModule.testQuery();       // Do something

或者,如果您愿意,可以像这样定义testQuery函数:

    mod.testQuery = function() {
        // Do something
    };

...但是这个函数是匿名的,我是not a fan of anonymous functions。 (请注意,名称MyModule_testQuery nothing 是特殊的,这纯粹是我的命名约定。)


有点偏离主题

关于我们在上面发布我们的全球符号的这一行:

// Create the global, and also give ourselves a convenient alias for it (`mod`)
window.MyModule = mod = {};

请注意,这非常特定于浏览器环境。我们可以通过一些微不足道的变化使其适用于任何JavaScript环境:

// Create the global, and also give ourselves a convenient alias for it (`mod`)
this.MyModule = mod = {};

这是有效的,因为我们是那些调用最外层范围函数的人,所以我们知道我们没有用JavaScript中的任何特定this值(this)调用它 - 与其他一些不同语言 - 根据函数的调用方式确定完全,而不是在何处或如何定义函数。因为我们知道我们没有使用任何特殊的this值,我们知道它将是全局对象,因为这就是JavaScript的工作原理。并且全局对象在Web浏览器上是window(实际上;技术上window是全局对象上的一个属性,它返回自身)。

答案 1 :(得分:1)

http://jsfiddle.net/vXu7m/1/

一些句法清理,并将MYGLOBALS附加到窗口对象应该做你想要的。