Javascript中的前向声明

时间:2011-09-19 11:04:01

标签: javascript oop javascript-objects

背景

我正在构建一个基于javascript的应用程序,它在移动和桌面设备上的工作方式不同。但是,除了DOM操作之外,大多数代码在两个平台之间都很常见,所以我构建了所有文件,如: * foo.core.js * foo.mobile.js * foo.web.js

希望利用面向对象技术编写更清晰的代码。

问题:

我有两个JavaScript文件,包含类

文件1:

function ClassA()
{}

ClassA.prototype.foo = function(){};

GreatGrandChildA.prototype = new GrandChildA(); // this is where the error is
function GreatGrandChildA ()
{}

文件2:

ChildA.prototype = new ClassA();
function ChildA () // ChildA inherits ClassA
{}

GrandChildA.prototype = new ChildA()
function GrandChildA () // GrandChildA inherits ClassA
{}

通常,在像C ++这样的语言中,我会在文件1中转发声明GrandChildA。我想知道如何在Javascript中执行此操作

编辑:

如果我创建一个包含所有四个类的单个文件 - 按照加载它们的顺序,该示例与预期完全一样:

http://jsfiddle.net/k2XKL/

4 个答案:

答案 0 :(得分:3)

无序js文件加载的简单逻辑:

File1中:

// ClassB: inherite from ClassA
(function ClassB_Builder() {
  if(window.ClassB)return; // ClassB is already defined;
  if(!window.ClassA) { // ClassA is already not defined;
     setTimeout(ClassB_Builder,0); // shedule class building
     return;
  }
  ClassB=function() {
  }
  ClassB.prototype=new ClassA;
  ClassB.prototype.constructor=ClassB; // can be important for inheritance!!!
})();

文件2:

// ClassA: base class
(function ClassA_Builder() {
  ClassA=function() {
  }
})();

// ClassC: inherite from ClassB
(function ClassC_Builder() {
  if(window.ClassC)return; // ClassC is already defined;
  if(!window.ClassB) { // ClassB is already not defined;
     setTimeout(ClassC_Builder,0); // shedule class building
     return;
  }
  ClassC=function() {
  }
  ClassC.prototype=new ClassB;
  ClassC.prototype.constructor=ClassC; // can be important for inheritance!!!
})();

答案 1 :(得分:1)

我假设您在HTML页面上导入文件1,然后导入文件2.

文件1 中,您应该会看到异常,因为“GrandChildA”是未定义。函数声明未完成,因为文件2尚未加载。

文件2 中,您可以执行以下操作:

ChildA.prototype = new ClassA();
function ChildA () // ChildA inherits ClassA
{}

因为Javacript运行时在代码执行之前将命名函数“ClassA”提升到ChildA.prototype = new ClassA();

请阅读有关功能提升的更多信息,如果您在http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

这种情况下应该这样做

答案 2 :(得分:1)

实现您想要的最明智的方法是制作2个独立版本的源代码。您将要缩小,混淆代码并合并所有源文件,因此创建构建脚本(python将是一个简单构建脚本的优秀语言)是有意义的,您可以将其配置为合并移动特定的文件合并为一个(加上两个版本共享的文件)和非移动特定文件到另一个文件(以及共享文件)。此外,您可以在以后添加自动混淆和gzipping。然后,您可以将适当的源版本提供给适当的客户端。

答案 3 :(得分:0)

如评论中所述,无法使用所请求的功能。 这不仅是一个技术问题,也是一个迹象 应用程序没有适当的结构 - 应该改进设计。 现在,有一种循环依赖应该避免。

为了比较,你提到你可以通过前向声明在C ++中解决它 超类。但这也是不可能的。在C ++中, 为了声明一个子类,你需要包含文件 超类的声明。当存在循环依赖时,你无法解决问题。