我正在编写一些 oop javascript 代码。我有一个类的几个实例,并将不同的数据放入每个实例中。不幸的是,正如您将在下面的示例中看到的那样,它们似乎共享相同的数据。
是否可以获取我的类的两个独立实例?将如何完成。
索引.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>
测试.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, 0, 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 中,对象直接继承自其他对象(它们所谓的原型(prototype))。您当前所指的类实际上是一个构造函数,当使用 new 关键字调用时,它将创建一个新对象,该对象将从存储在构造函数原型(prototype)字段中的任何对象继承。
var anObject = {
key: 'value'
};
function MakeAnObject() {
}
MakeAnObject.prototype = anObject;
var o = new MakeAnObject();
console.log(o.key); // will output 'value'
如果您设置一个属性,该属性将始终设置在对象本身上,在设置属性时它永远不会访问原型(prototype)链。
如果您读取一个对象的属性,但对象没有该属性,JavaScript 将在对象原型(prototype)链(即所有相互继承的对象)中搜索该属性并返回如果找到它。
如果一个对象本身有一个属性,它的原型(prototype)链将不会被搜索,所以你可以通过在对象自身上设置属性来“覆盖”对象继承的属性。
看下面的例子:
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 中的对象没有公共(public)成员和私有(private)成员这样的东西。成员将始终公开。有一些模式试图使用闭包隐藏对象中的某些信息,但它们的功能与传统编程语言中的私有(private)成员有很大不同。更糟糕的是:这些模式很笨重,会产生糟糕且性能非常差的代码。如果您不是绝对需要,我建议不要使用它们。
那么,这一切意味着什么呢?首先,如果你想在多个对象之间共享属性和方法,它们将必须继承自同一个原型(prototype),并且该原型(prototype)必须包含这些属性和方法。其次,如果您在 this 上设置某些内容,它将在当前实例上设置,而不是在原型(prototype)上设置。第三,按照惯例只有私有(private)和公共(public)成员。如果您绝对需要对某个子系统严格隐藏某些信息,可以使用一些模式(Crockford sealer unsealer 应该产生可用的结果)。
所有这些都在这里快速尝试修复你的对象:
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, 0, 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 .路过这里的任何人都可能对此感兴趣。
关于Javascript OOP/类 - 多个实例共享相同的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7002946/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat