te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>oop - Forward declaration in Javascript - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

oop - Forward declaration in Javascript - Stack Overflow

programmeradmin3浏览0评论

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 mon between both platforms, so I have structured all files like: * 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

File 1:

function ClassA()
{}

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

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

File 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 GrandChildA right in File 1. I would like to know how to do it in 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:

/

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 mon between both platforms, so I have structured all files like: * 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

File 1:

function ClassA()
{}

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

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

File 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 GrandChildA right in File 1. I would like to know how to do it in 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/k2XKL/

Share Improve this question edited Sep 19, 2011 at 11:38 antileet2 asked Sep 19, 2011 at 11:04 antileet2antileet2 3231 gold badge2 silver badges7 bronze badges 6
  • Let me get this straight - you want to assign new instance of an class GrandChildA before it has been declared? Javascript natively doesn't support any way to do that. – WTK Commented Sep 19, 2011 at 11:22
  • When using plain javascript (without helper libraries) you must download js-file that contains parent class definition before js-file that contains child class definition. For your example: File2 must be downloaded before File1. Or you can merged both files into one. If you need way to download childs classes before parent, you can use external library or implement your custom logic for downloading and creating classes. – Andrew D. Commented Sep 19, 2011 at 11:32
  • @WTK: If I put everything in one file, it works great. Unfortunately, the way I've designed it prevents putting everything in one file. but now it looks like I'll have to re-structure the entire application. – antileet2 Commented Sep 19, 2011 at 11:35
  • @Andrew - The problem is that the scripts are executing one after the other. So no matter which code executes first, it'll fail. Funnily enough putting both the scripts in the same file solves the issue. But that's something I Cannot do – antileet2 Commented Sep 19, 2011 at 11:37
  • @skyronic yes you may need to re-structure your code organization. And read about hoisting in Javascript runtime to understand why your File 2 actually works – Kenny Ki Commented Sep 19, 2011 at 11:45
 |  Show 1 more ment

4 Answers 4

Reset to default 6

Simple logic for unordered js file loading:

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

File2:

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

I assume that on your HTML page, you import File 1 and then File 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.

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

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

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

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

The most sane way to acplish 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.

As mentioned in the ments, 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 parison 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 include the file with the declaration of the superclass. And you cannot solve the problem when there are circular dependencies.

发布评论

评论列表(0)

  1. 暂无评论