改变JavaScript的全局对象?

Van*_*ing 7 javascript

有没有办法在JavaScript中更改根对象?

例如,在浏览器中,根对象是"窗口".所以

X = 5;
console.log(Y);
Run Code Online (Sandbox Code Playgroud)

是相同的:

window.X = 5;
console.log(window.Y);
Run Code Online (Sandbox Code Playgroud)

我现在要做的是更改此根对象,所以当我执行以下操作时:

X = 6;
Run Code Online (Sandbox Code Playgroud)

我需要这个的原因:

在Node.js应用程序中,程序的每个部分都可以访问全局对象.这是一个大问题,因为Node.js网络服务器执行的每个脚本都可以向其添加新变量.他们将在那里,直到网络服务器重新启动.我想通过更改全局对象来避免这种情况.

更新

我测试了以下代码,得到了一个非常有趣的结果.您对以下代码的期望是什么?

var X = {A:"a",B:"b"};

with(X){
    A = 5;
    C = 7;
}
for(a in X){
    console.log(a+" is "+X[a]);
}

/* 
Expected Console Output:
A is 5
B is b
C is 7

Real Console Output:
A is 5;
B is b;

*/
Run Code Online (Sandbox Code Playgroud)

有没有办法像我预期的那样获得输出?

更新

我现在用以下代码测试模块系统.

//program.js
var t = require("./module.js");
t.Test();

console.log(A);

//module.js
A = 5;
exports.Test = function(){
    console.log("hello world!");
}
Run Code Online (Sandbox Code Playgroud)

输出是:

hello world!
5
Run Code Online (Sandbox Code Playgroud)

这告诉我,定义的变量"A" module.js被添加到全局对象中program.js.该模块也没有解决我的问题.

Que*_*tin 6

还有就是用语句,但不建议并严格禁止模式.

最好明确地引用保存对象的变量.

针对更新的问题:

with将搜索范围链,直到找到具有匹配属性的对象或者到达window.在对象上定义新属性没有好处.

var X = { A: 5, B: 8, C: 7};
with(X){
    console.log(A, B, C);
}
Run Code Online (Sandbox Code Playgroud)

  • @Flash:我确信我不像@David那样熟悉`with`语句,但似乎`with`在`X`中查找属性,如果没有找到,它会遍历作用域链。如果没有找到,它将创建全局变量。似乎使用了“with”,您需要首先定义这些属性。`var X = {A:null,B:null,C:null,D:"D"};` (2认同)

use*_*716 5

如果你在谈论变量,JavasScript有功能范围.

X = 5;  // global variable

console.log( window.X );  // 5

(function() {
   var X = 6;  // declare a local variable by using the "var" keyword

   console.log( X );  // 6
})();

console.log( window.X );  // 5
Run Code Online (Sandbox Code Playgroud)

否则,您可以创建一个Object,并为其添加属性.

X = 5; 

console.log( window.X );  // 5

var obj = {};

obj.X = 6;

console.log( obj.X ); // 6

console.log( window.X );  // 5
Run Code Online (Sandbox Code Playgroud)

编辑:添加另一种可能该解决方案可以被使用.

您可以调用匿名函数,但将函数的上下文设置为您的X对象.然后this在函数中将参考X.

var X = {};
(function(){
    this.A = 5;
    this.B = 8;
    this.C = 7;
}).call(X);
for(a in X){
    console.log(a+" is "+X[a]);
}
Run Code Online (Sandbox Code Playgroud)

该.call()方法(以及.apply()方法)允许您显式设置thisArgof a calling context. The first argument you pass will be how this`是在调用的上下文中定义的.

或者只是X作为参数传递.

var X = {};
(function(X){
    X.A = 5;
    X.B = 8;
    X.C = 7;
})(X);
for(a in X){
    console.log(a+" is "+X[a]);
}
Run Code Online (Sandbox Code Playgroud)

虽然最简单的是简单地引用它(正如我在上面的答案中所指出的).

var X = {};
X.A = 5;
X.B = 8;
X.C = 7;
for(a in X){
    console.log(a+" is "+X[a]);
}
Run Code Online (Sandbox Code Playgroud)

或使用模块模式:

   /****** I'm guessing at the use of "global" here ********/
global.myNamespace = (function(global,undefined) {

    // define the object to be returned
    var X = {};

    //  define private local variables
    var a_local = 'some value';
    var another_local = 'some other value';

    // define private functions
    function myFunc() {
        // do something with local variables
    }

    // give the return object public members
    X.someProperty = 'some value';
    X.anotherProperty = 'another value';
    X.publicFunc = function() {
        //do something with the local variables
        //    or public properties
    };
    X.anotherFunc = function() {
        //do something with the local variables
        //    or public properties
    };
    // return the object
    return X;

})(global);

console.log(myNamespace);
Run Code Online (Sandbox Code Playgroud)