Javascript 中的前向声明

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7469919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 00:13:47  来源:igfitidea点击:

Forward declaration in Javascript

javascriptoopjavascript-objects

提问by antileet2

Background

背景

I'm building a javascript based application that works differently on mobile and desktop devices. However, except for the DOM manipulation, most code is common between both platforms, so I have structured all files like: * foo.core.js * foo.mobile.js * foo.web.js

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

And hoping to leverage object oriented techniques to write cleaner code.

并希望利用面向对象的技术来编写更简洁的代码。

Problem:

问题:

I have two JavaScript files, with classes

我有两个带有类的 JavaScript 文件

File 1:

文件 1:

function ClassA()
{}

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

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

File 2:

文件2:

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

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

Normally, in a language like C++, I would forward declare GrandChildAright in File 1. I would like to know how to do it in Javascript

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

Edit:

编辑:

If I make a single file containing all four classes - in the same order in which they are loaded, the example works exactly as expected:

如果我制作一个包含所有四个类的单个文件 - 按照加载它们的相同顺序,该示例完全按预期工作:

http://jsfiddle.net/k2XKL/

http://jsfiddle.net/k2XKL/

采纳答案by Andrew D.

Simple logic for unordered js file loading:

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

File1:

文件1:

// 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!!!
})();

File2:

文件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!!!
})();

回答by Kenny Ki

I assume that on your HTML page, you import File 1 and then File 2.

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

In File 1, you should see exception because "GrandChildA" is undefined. The function declaration is not done because File 2 has not loaded yet.

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

In File 2, you're being able to do:

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

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

because the Javacript runtime hoisted your named function"ClassA" beforethe code executes until ChildA.prototype = new ClassA();

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

Please read more about function hoisting and should you be doing it in such situation at http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

请在http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting阅读有关函数提升的更多信息以及您是否应该在这种情况下执行此操作

回答by zatatatata

The most sane way to accomplish what you want, is to make 2 separate versions of your source code. You're going to want to minify, obfuscate your code and merge all the source files anyway, so it would make sense to create a build script (python would be a great language for a simple build script) that you configure to merge mobile specific files into one (plus the files that both versions share) and non-mobile specific files into another file (and shared files also). In addition you could later add automatic obfuscating and gzipping. Then you can serve the appropriate source version to the appropriate client.

完成您想要的最明智的方法是制作 2 个独立版本的源代码。无论如何,您将想要缩小、混淆您的代码并合并所有源文件,因此创建一个构建脚本(python 对于简单构建脚本来说是一种很好的语言)是有意义的,您将其配置为合并移动特定的将文件合并为一个(加上两个版本共享的文件),并将非移动特定文件合并到另一个文件(以及共享文件)。此外,您可以稍后添加自动混淆和 gzip 压缩。然后您可以为适当的客户端提供适当的源版本。

回答by Jiri Kriz

As mentioned in the comments, the requested functionality is not possible. This is not only a technical problem but also an indication that the application is not structured appropritately - the design should be improved. Now, there is a kind of a circular dependency that shoul be avoided.

正如评论中提到的,请求的功能是不可能的。这不仅是一个技术问题,而且表明应用程序的结构不恰当——设计应该改进。现在,有一种应该避免的循环依赖。

For comparison you mention that you would solve it in C++ by a forward declaration of the superclass. But this is also not possible. In C++, in order to declare a subclass you need to includethe file with the declaration of the superclass. And you cannot solve the problem when there are circular dependencies.

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