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