是否有可能获得我班级的两个独立实例?怎么做呢
的index.html
<html> <head> <Meta http-equiv="Content-type" content="text/html; charset=utf-8"> <script type="text/javascript" src="test.js"></script> <script type="text/javascript"> debugger; // Do this because a page resart seems to keep old data function SetGlobals() { var ui; var el; // Arr00 ui = document.getElementById("Arr00"); el = arr0.arrayGet(0); ui.innerHTML = el.m_String; // Arr01 ui = document.getElementById("Arr01"); el = arr0.arrayGet(1); ui.innerHTML = el.m_String; // Arr10 ui = document.getElementById("Arr10"); el = arr1.arrayGet(0); ui.innerHTML = el.m_String; // Arr11 ui = document.getElementById("Arr11"); el = arr1.arrayGet(1); ui.innerHTML = el.m_String; } function MyOnLoad() { SetGlobals(); } </script> </head> <body onload="MyOnLoad()" style="width:100%; height: 100%; padding: 0 0 0 0; margin: 0 0 0 0; overflow: hidden; background:#000000"> <div id="divScreen" style="display: block; width:100%; height="100%"> <div id="divMenu" style='float: left; background:#00FF00; border-color: #000000; border-width: 1px;'> <table> <tr> <td> Array 0/String 0: <label id="Arr00"></label> </td> </tr> <tr> <td> Array 0/String 1: <label id="Arr01"></label> </td> </tr> <tr> <td> Array 1/String 0: <label id="Arr10"></label> </td> </tr> <tr> <td> Array 1/String 1: <label id="Arr11"></label> </td> </tr> </table> </div> <div id="divMain" style='height: 100%; background:#0000FF; margin-left: 250px; border-color: #000000; border-width: 1px;'> </div> </div> </body> </html>
Test.js
var BaseARR = function() { _arr = []; // new Array(); // Public functions that can access private members this.Add = function(arg) { var i,addAt; if(arg==null || (addAt = FindEnterPos(arg))<0) return false; // since adding and not deleting anything,nothing of value will be returned _arr.splice(addAt,arg); return true; }; // This finds the entry position for in FindEnterPos = function(arg) { return (_arr.length + 1); }; this.arrayGet = function(i) { return ((_arr != null && i >= 0 && i < _arr.length) ? _arr[i] : null); }; }; var stringId = function(id,str) { // public has a this.,privates have just var this.m_Id = id; // int this.m_String = str; // string }; // This so allow statics var stringIdARR = function() { BaseARR.call(this); };
解决方法
首先,强烈建议不要在JavaScript中将开放块括号放在一行上.为什么你会问?运行这两个代码片段:
// using "braces on same line" style (function () { return { key: 'value' }; })(); // using "braces on line by themself"-style (function () { return { key: 'value' } })();
两个片段都会返回不同的结果,尽管唯一的区别是大括号的位置.其原因是分号插入.在JavaScript中,分号是可选的.因此,如果解析器找到换行符并且换行符前面的构造有意义,它将插入分号.在第二个例子中,这是在return语句之后发生的事情.如果将大括号放在与前一个语句相同的行上,则可以规避此类错误.
接下来你错了就是JavaScript有类. JavaScript是一种面向对象的语言,但与大多数其他面向对象语言不同,它没有类.在JavaScript中,对象直接从其他对象(它们所谓的原型)继承.你当前所指的是一个类实际上是一个构造函数,当使用new关键字调用时,它将创建一个新对象,它将从构造函数原型字段中存储的任何对象继承.
var anObject = { key: 'value' }; function MakeAnObject() { } MakeAnObject.prototype = anObject; var o = new MakeAnObject(); console.log(o.key); // will output 'value'
如果设置属性,则在对象本身上设置proerty,在设置属性时永远不会访问原型链.
如果您从一个没有该属性的对象中读取属性,JavaScript将搜索该属性的对象原型链(即所有相互继承的对象),如果找到则返回它.
如果一个oject本身有一个属性,它的原型链就不会被搜索,所以你可以通过在对象self上设置porperty来“覆盖”一个对象继承的属性.
请看以下示例:
function MakeThing() { } MakeThing.prototype = { key: 'value' }; var o1 = new MakeThing(),o2 = new MakeThing(); console.log(o1); // will output 'value' console.log(o2); // will output 'value' o2.key = 'other'; console.log(o1); // will output 'value' console.log(o2); // will output 'other' MakeThing.prototype.key = 'changed'; console.log(o1); // will output 'changed' console.log(o2); // will output 'other' delete o2.key; console.log(o1); // will output 'changed' console.log(o2); // will output 'changed'
考虑到所有这些,我将不得不告诉你:在JavaScript中的对象上没有公共和私有成员这样的东西.会员将永远是公开的.有些模式试图使用闭包来隐藏对象中的某些信息,但它们的功能与传统编程语言中的私有成员非常不同.更糟糕的是:这些模式很笨重,产生了糟糕且非常糟糕的代码.我建议如果你没有绝对要求,不要使用它们.
那么,这意味着什么?首先,如果要在多个对象之间共享属性和方法,则必须从同一原型继承,并且该原型必须包含这些属性和方法.其次,如果您在此设置某些内容,它将在当前实例上设置,而不是在原型上设置.第三,只有按惯例设立priavte和公共成员.如果您绝对要求某些子系统严格隐藏某些信息,那么就有这样的模式(Crockford封口机开封应该会产生可用的结果).
所有这些都说明了在修复对象时的快速尝试:
function BaseAAR { this._arr = []; // note >this<. You created a global array in your code. }; BaseAAR.prototype.add = function(arg) { var i,addAt; // always use identity (triple) operators when comparing to null! if (arg === null || (addAt = this.findEnterPos(arg))<0) return false; // since adding and not deleting anything,nothing of value will be returned this._arr.splice(addAt,arg); return true; }; // This finds the entry position for in BaseAAR.prototype.findEnterPos = function() { return (this._arr.length + 1); }; BaseAAR.prototype.arrayGet = function(i) { return ((this._arr !== null && i >= 0 && i < this._arr.length) ? this._arr[i] : null); }; function StringIdAAR(id,str) { BaseAAR.call(this); // invoke the constructor of the base object this.m_Id = id; // int this.m_String = str; // string } StringIdAAR.prototype = BaseAAR.prototype; // innherit from StringIdAAR prototype
我不完全确定这段代码是否真的仍然按照你的意愿去做,但你应该明白JavaScript中面向对象的模式应该是什么样子.
如果你想阅读更多关于如何编写好的JavaScript的信息,你应该完全得到Douglas Crockford的书“JavaScript:The Good Parts”.
更新:我还写了一个article on JavaScript object orientation and prototype based inheritance.这可能是路过这里的人感兴趣的.