为什么JavaScript中的子对象会失去全局作用域
Why does a child object in JavaScript lose the global scope?
我正在努力遵循Douglas Crockford在"JavaScript:The Good Parts"和他的网站上的建议
应尽量减少使用全局变量。隐含全局变量不应使用。
为了做到这一点,我定义了一个"根"对象,它充当所有其他对象的容器,现在一切都被安排到共享功能的逻辑层次结构中。
让我困惑的是,子对象似乎失去了全局对象的范围。我能想到的最好的例子是我的记录器,我想将其全局定义为root.log,并在其他地方重用它。
但是,当我尝试访问子对象内部的root.log时,我的代码失败了,因为它再也看不到对root对象的任何引用。我将子对象移到全局范围中,它会再次看到一切正常。
我在Stack Overflow上看到过其他帖子,它们通过显式地将父引用转发到子对象中,为父/子对象通信提供了解决方案,但这并不是我真正想要的。我希望能够从任何一点访问根,如果我落后三到四级,我不想再处理追踪链的问题。
一个明确的例子可能是,如果我在实用程序层次结构的深处,并且我想记录一条消息。假设我在root.util.array.getPositionInArray(),并且我已经将父值传递到每个子对象中。我不想调用parent.parent.log.write,我只想简单地调用root.log.write.
我可以在创建每个子对象时将根对象和父对象引用传递给它们,或者尝试一些继承原则,看看是否能让它以这种方式工作。
我的问题如下:
-
当我在另一个对象内部定义的对象中时,为什么全局作用域会"消失"?
-
有没有一种简单的方法可以从子对象内部访问全局变量?
-
(可能是2的副本)处理此问题的建议方法是什么?
我的示例代码如下(此处加载到jsfiddle中)
// declare root object as global variable
var root = null;
$(document).ready(function() {
// instantiate root
root = new Foo();
// uncomment to instantiate child separately
// child = new ChildFoo();
// write to log from outside parent (shows scope is global)
root.log.write(root.x)
root.log.write(root.child.x);
});
function Foo() {
// instantiate logger as child of parent
this.log = new Logger("output");
// write a quick message
this.log.write("Foo constructor");
// set value of x
this.x = 1;
// instantiate child object
this.child = new ChildFoo;
}
// child object definition
function ChildFoo() {
// why is root.log == null here?
root.log.write("Child constructor");
// this reference to parent also fails
// this.x = 10 * root.x;
this.x = 10;
}
// log object definition
function Logger(container) {
// store reference to dom container
this.container = container;
}
// method to write message to dom
Logger.prototype.write = function(message) {
$("#" + this.container).append("[" + new Date() + "] " + message + "<br>");
}
我已经能够通过在Foo对象定义的顶部添加以下部分来实现这一点。这立即提供了对根对象的全局对象引用,还实现了Singleton模式,以确保只有一个根对象。jsfiddle已经完全更新了。
if(root != null){
root.log.write("Root object already instantiated");
return root;
} else {
root = this;
}
问题是您正在调用。。。
var parent = null;
$(document).ready(function() {
parent = new Foo();
// ...
});
它调用CCD_ 1。。。
this.log = new Logger("output");
this.log.write("Foo constructor");
this.x = 1;
this.child = new ChildFoo;
其调用ChildFoo
、尝试访问parent
。。。
parent.log.write("Child constructor");
这是一次调用,因此在尝试访问parent
之前,原始new Foo
尚未完成,因此parent
仍然是null
。
- 全局变量和全局对象的属性之间有什么区别吗
- 正在全局范围中查找JavaScript函数
- delete关键字在全局变量上的不同行为
- 在javascript函数中设置全局变量
- 如何将getJson的响应保存在全局变量中
- 全局对象是属于哪个类的对象
- Javascript全局onclick监听器
- 从Javascript方法返回全局变量
- Javascript游戏输入失去焦点
- 访问jsrender模板中的全局javascript变量并更新它
- jquery日期选择器失去了交互性
- javascript无法重新定义函数内部的全局对象
- javascript 中的全局函数
- cordova:例外:财产'requestFileSystem'的[对象全局]不是函数
- 全局安装gull后出错
- AngularJS中的封装窗口全局变量
- 失去全局变量值
- Javascript 局部和全局变量在回调函数中失去作用域
- 为什么JavaScript中的子对象会失去全局作用域
- 全局变量在从另一个js文件访问时失去它的值