Javascript:final / immutable全局变量?

时间:2009-03-20 02:50:20

标签: javascript

我想我知道答案但是......有没有办法阻止全局变量被后来执行的<script>修改?我知道全局变量首先是坏的,但是在必要时,有没有办法让它“最终”或“不可变”?欢迎黑客/创意解决方案。感谢

14 个答案:

答案 0 :(得分:47)

const 关键字?

答案 1 :(得分:14)

你可以使用闭包技术,MYGLOBALS是一个对象,它有一个名为getValue的函数来对抗“globals”关联数组,这个数组超出了除MYGLOBALS实例之外的所有内容。

var MYGLOBALS = function() {
    var globals = {
        foo : "bar",
        batz : "blah"       
    }
    return { getValue : function(s) {
            return globals[s];
        }
    }
}();
alert(MYGLOBALS.getValue("foo"));  // returns "bar"
alert(MYGLOBALS.getValue("notthere")); // returns undefined
MYGLOBALS.globals["batz"] = 'hardeehar'; // this will throw an exception as it should

答案 2 :(得分:11)

我知道这个问题很旧,但你可以使用Object.freeze(yourGlobalObjectHere); 我刚刚写了一篇关于它的博客文章here

答案 3 :(得分:9)

是的,const在某些语言中是常​​数或最终的缩写。 google“javascript变量const”或常量加倍我甚至自己测试过它

const yourVar = 'your value';

那就是你要找的东西。

答案 4 :(得分:4)

这将是更清洁的方法

   var CONSTANTS = function() {
        var constants = { } ; //Initialize Global Space Here
        return {
            defineConstant: function(name,value)
            {
                if(constants[name])
                {
                   throw "Redeclaration of constant Not Allowed";
                }
            },
            getValue(name)
            {
               return constants[name];
            }
        } ;
    }() ;
    CONSTANTS.defineConstant('FOO','bar') ;
    console.log(CONSTANTS.getValue('FOO')) ; //Returns bar
    CONSTANTS.defineConstant('FOO','xyz') ; // throws exception as constant already defined
    CONSTANTS.getValue('XYZ') ; //returns undefined

答案 5 :(得分:3)

试试这个:

const whatEver = 'Hello World!!!';

function foo(value){
 whatEver = value;
}

然后你会这样称呼它......

<div onclick="foo('New Value');">Change Me First</div>
<div onclick="alert(whatEver);">Then click me After: Should Be alert "Hello World!!!"</div>

答案 6 :(得分:2)

选择一个不太可能被意外覆盖的变量名称,并相信程序员不要做愚蠢的事情。 JavaScript不是Java,所以不要假装它。

另外,如果您真正想做的是命名空间,请使用自动执行的函数文字:

var myLibName = (function() {
    var aPrivateVar;

    function aPrivateFunction() {}

    function accessorForPrivateVar() {
        return aPrivateVar;
    }

    // public interface:
    return {
        getPrivateVar : accessorForPrivateVar
    }
})();

答案 7 :(得分:2)

http://ejohn.org/ @ http://ejohn.org/blog/ecmascript-5-objects-and-properties/

的代码怎么样?

看起来这确实有用......我运行一些“小”测试并冻结变量和属性。

  

冻结物体是锁定的最终形式。曾经是一个对象   已被冻结,它不能解冻 - 也不能被篡改   方式。这是确保您的对象保持不变的最佳方法   正如你离开他们一样,无限期。

Object.freeze = function( obj ) {
  var props = Object.getOwnPropertyNames( obj );

  for ( var i = 0; i < props.length; i++ ) {
    var desc = Object.getOwnPropertyDescriptor( obj, props[i] );

    if ( "value" in desc ) {
      desc.writable = false;
    }

    desc.configurable = false;
    Object.defineProperty( obj, props[i], desc );
  }

  return Object.preventExtensions( obj );
};

小例子

var config = (function (__name) {
    name: __name
    var _local = {
        Server: "SomeText",
        ServerDate: "SomeServerDate",
        JSDate : Util.today(),
        User : {
            user: "1stUser",
            name: "",
            email: ""
        },        
    }

    /*Private Methods*/
    function freezing(__array) {
        $.each(__array, function (_index, _item) {
            Object.freeze(_item);
        });
    }

    /*Public Methods*/
    var $r = {};

    $r.info = function () {
        return _local;
    }

    freezing([
        _local,
        _local.User
    ]);


    _local.User.user = "newUser"; //Trying to assing new value

    //Remain with the same value as first declaration
    console.log(_local.User.user); //--> "1stUser"           
    return $r;
})("config");

答案 8 :(得分:2)

Object.defineProperty(window, 'CONSTANT_NAME', {value: CONSTANT_VALUE});

// usage
console.log(CONSTANT_NAME);

Object.defineProperty()使用以下默认属性创建属性:

  • configurable 当且仅当此属性描述符的类型可能更改且属性可能从相应对象中删除时才为true。 默认为false。

  • enumerable 当且仅当在枚举相应对象的属性期间显示此属性时才显示true。 默认为false。

  • writable 当且仅当与属性关联的值可能会使用赋值运算符更改时才为true。 默认为false。

如果“常量”是一个对象,你可能还想通过冻结它使它变得不可变。 obj = Object.freeze(obj)。请记住,子属性对象不会自动冻结。

答案 9 :(得分:1)

约定和良好的文档。

您可以在“不可变”变量前加上两个(或更多)下划线,以表明其他人不应该使用这些变量,并避免其他人的变量与您的变量发生冲突。

也许创建一个'{1}}之类的'命名空间'(丑陋的名字,我知道),然后将变量添加到其中(例如__GLOBALNAMESPACE)并创建一个像这样的方法来检索它们:

__GLOBALNAMESPACE.my_var

只需2美分。

答案 10 :(得分:1)

不是在全局范围内声明所有这些变量,而是可以让一个全局对象包围这些变量。使用Object.defineProperty()和/或Object.defineProperties()并将writable标志设置为false,您可以拥有一个不可变变量。

var myObj = {};

Object.defineProperty(myObj, 'myVar', {
    value: someValue,
    writable: false
});

或者你可以使用const keyword

const MY_VAR = 10;

答案 11 :(得分:0)

您可能想试试这个jquery plugin。它阻止你在javascript :)中创建全局对象。

示例代码

存储数据

// 'val' can be a string, integer, hash table, array, object
$.secret( 'in', 'secretName', val );

// or a function
$.secret( 'in', 'secretName', function( arg1, arg2, arg3 ){
  // do something here
});

使用数据;你甚至可以在不同的文件中使用它。

var lang = $.secret( 'out', 'lang' );

调出一个函数

$.secret( 'call', 'secretName', [ arg1, arg2, arg3 ]);
// or
$.secret( 'call', 'secretName', arg );

清除数据

$.secret( 'clear', 'lang' );

源代码位于github

答案 12 :(得分:0)

Javascript是面向对象的,而不是使变量 $ public static ,考虑将其设为私有,然后正确地提供获取方法,但不设置它。

e.g。

private var myGlobal : myType;
function GetMyGlobal() : myType
{
return myGlobal;
}
  

有十种不同的方法可以解决任何问题,方法和方法。

答案 13 :(得分:0)

如果您可以使用打字稿,则可以将属性标记为readonly