更改JavaScript';什么是全局对象?

更改JavaScript';什么是全局对象?,javascript,Javascript,有没有办法在JavaScript中更改根对象 例如,在浏览器中,根对象是“窗口”。所以 同: window.X = 5; console.log(window.Y); 我现在要做的是更改此根对象,因此当我执行以下操作时: X = 6; 我需要这个的原因: 在应用程序中,程序的每个部分都可以访问全局对象。这是一个大问题,因为Node.js Web服务器执行的每个脚本都可以向其中添加新变量。它们将一直存在,直到重新启动Web服务器。我希望通过更改全局对象来避免这种情况 更新 我测试了以下代码,得

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

例如,在浏览器中,根对象是“窗口”。所以

同:

window.X = 5;
console.log(window.Y);
我现在要做的是更改此根对象,因此当我执行以下操作时:

X = 6;
我需要这个的原因:

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

更新

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

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;

*/
有没有一种方法可以像我预期的那样获得输出

更新

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

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

console.log(A);

//module.js
A = 5;
exports.Test = function(){
    console.log("hello world!");
}
结果是:

hello world!
5
这告诉我,
module.js
中定义的变量“A”被添加到
program.js
的全局对象中。该模块也不能解决我的问题。

有这样的声明,但在严格模式下不建议和禁止使用该模块

最好显式引用保存对象的变量

回应最新问题:

with
将向上搜索范围链,直到找到具有匹配属性的对象或进入
窗口
。在对象上定义新属性是没有用的

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

如果您谈论的是变量,那么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
否则,可以创建对象,并向其添加属性

X = 5; 

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

var obj = {};

obj.X = 6;

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

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

编辑:添加另一个可能使用的解决方案

您可以调用匿名函数,但将函数的上下文设置为
X
对象。然后
该函数中的
将引用
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]);
}
.call()
方法(以及
.apply()
方法)允许您显式设置调用上下文的thisArg
。您传递的第一个参数是
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]);
}
尽管最简单的方法是简单地引用它(正如我在上面的回答中所指出的)


或使用模块模式:


我在EcmaScript 6中找到了一种方法,可以使用(context){…}
调整
,这样我们分配的任何新变量都将进入
上下文
对象,而不是全局/
窗口
对象

感谢本文教我ES6代理功能

在代理中:

  • 我们重写
    has
    以返回
    true
    ,因此我们的上下文似乎具有所有属性,当我们设置任何变量时,它将转到对象
  • 我们重写
    get
    以从上下文中获取属性,或者如果它实际上不在上下文中,则从
    向上
    对象(默认为全局
    窗口
    )获取属性
我知道
with
是不受欢迎的,但是这种技术可以创建可变的可扩展模块,我们可以通过
foo
而不是
Module.foo
方便地访问成员,我不认为这是不安全的或模棱两可的

功能范围(x,up=window){
返回新代理(x{
has:(o,k)=>正确,
get:(o,k)=>k in o?o[k]:向上[k]
});
}
var检验={};
(范围(测试)){
x=1;
y=2;
添加_x=函数(y){
控制台日志(x+y);
}
}
测试。添加_x(10);
(范围(测试)){
x=3;
添加_y=函数(x){
控制台日志(x+y);
}
}
测试。添加_x(20);
试验y=5;

测试。添加_y(30)@Down投票人:请解释。我的回答哪一部分不正确?@David:谢谢你的回答。你能解释一下那是哪一位吗?我认为OP不熟悉javascript,因此当OP确实
X=5
,并看到它向
窗口添加属性时,我猜想有一种假设是,这就是通常添加属性的方式。根据具体需要,这两种解决方案中的任何一种都有助于IMO+1给出一个非常好的答案。但是David的答案与我期望的解决方案最为接近。顺便说一句,我想解释一下为什么我要像发布它那样做:在Node.js应用程序中,程序的每个部分都可以访问全局对象。这是一个大问题,因为Node.js Web服务器执行的每个脚本都可以向其中添加新变量。它们将一直存在,直到重新启动Web服务器。我想通过更改全局对象来避免这种情况。@FlashFan:我知道你的意思,但是如果你不小心的话,
with
会(正如你现在知道的)产生意想不到的结果。我可能错了,但听起来您好像在为代码寻找一个新的变量范围。在javascript中实现这一点的唯一方法是使用函数。没有块作用域(除了非标准的
let
关键字,我不相信
V8
实现了它)。我想用
(如果您还没有)去掉
,使用一个唯一的全局名称空间,使其不会被覆盖,然后在立即调用的函数表达式中执行代码操作。谢谢!我完全忘了“with”,这正是我要找的。禁止与否无关紧要。它必须只能在V8引擎中运行,而且它似乎可以工作。好的,我要快一点。。。它不像我预料的那样工作。我更新了我的帖子。@Flash:我肯定我对
with
语句的熟悉程度不如@David,但似乎
with
X
中查找属性,如果没有找到,它将遍历范围链。如果找不到,它将创建全局变量。如果将
一起使用,则需要首先定义这些属性<代码>变量X={A:null,B:null,C:null,D:“D”}var X = {}; (function(X){ X.A = 5; X.B = 8; X.C = 7; })(X); for(a in X){ console.log(a+" is "+X[a]); }
var X = {};
X.A = 5;
X.B = 8;
X.C = 7;
for(a in X){
    console.log(a+" is "+X[a]);
}
   /****** 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);