Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript OOP/类-多个实例共享相同的数据_Javascript_Oop_Class - Fatal编程技术网

Javascript OOP/类-多个实例共享相同的数据

Javascript OOP/类-多个实例共享相同的数据,javascript,oop,class,Javascript,Oop,Class,我正在编写一些面向对象的javascript代码。我有一个类的几个实例,每个实例中都有不同的数据。不幸的是,正如下面的示例所示,它们似乎共享相同的数据 可以得到我的类的两个独立实例吗?怎么做呢 Index.html <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <script type="text/javascript" src="te

我正在编写一些面向对象的javascript代码。我有一个类的几个实例,每个实例中都有不同的数据。不幸的是,正如下面的示例所示,它们似乎共享相同的数据

可以得到我的类的两个独立实例吗?怎么做呢

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>

调试器;
//这样做是因为页面重新启动似乎保留了旧数据
函数SetGlobals()
{
var-ui;
var-el;
//啊
ui=document.getElementById(“Arr00”);
el=arr0.arrayGet(0);
ui.innerHTML=el.m_字符串;
//Arr01
ui=document.getElementById(“Arr01”);
el=arr0.arrayGet(1);
ui.innerHTML=el.m_字符串;
//Arr10
ui=document.getElementById(“Arr10”);
el=arr1.arrayGet(0);
ui.innerHTML=el.m_字符串;
//Arr11
ui=document.getElementById(“Arr11”);
el=arr1.阵列集(1);
ui.innerHTML=el.m_字符串;
}
函数MyOnLoad()
{
SetGlobals();
}

对于一个优秀的JavaScript继承示例,请看一下John Resig的实现。我已经使用它的一个修改版本有一段时间了。这将更详细地描述它

另一个提供类似功能的库是,但对于您的需求来说可能有些过头了


最后,我过去也使用过的另一种流行方法是。有关该模式的深入解释,请参见此部分。

代码中存在各种问题。让我来解释一下

首先,强烈建议不要在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
关键字调用它时,它将创建一个新对象,该对象将继承存储在constructors prototype字段中的任何对象

var anObject = {
  key: 'value'
};
function MakeAnObject() {
}

MakeAnObject.prototype = anObject;

var o = new MakeAnObject();

console.log(o.key); // will output 'value'
如果设置属性,则该属性将在对象本身上设置,在设置属性时,它将永远不会访问原型链

如果从没有该属性的对象中读取属性,JavaScript将在对象原型链(即相互继承的所有对象)中搜索该属性,并在找到时返回该属性

如果一个项目本身有一个属性,它的原型链将不会被搜索,因此您可以通过在对象本身上设置属性来“覆盖”对象继承的属性

请看以下示例:

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中,对象上没有公共成员和私有成员。成员将始终是公开的。有些模式试图使用闭包隐藏对象中的某些信息,但它们的功能与传统编程语言中的私有成员非常不同。更糟糕的是:这些模式很笨重,会产生糟糕的代码。我建议不要使用它们,如果你没有绝对的要求

那么,这一切意味着什么?首先,如果你想在多个对象之间共享属性和方法,它们必须从同一个原型继承,原型必须包含这些属性和方法。其次,如果您在
上设置了一些内容,那么它将在当前实例上设置,而不是在原型上设置。第三,只有按照惯例才有议会成员和公众成员。如果您绝对需要对某个子系统严格隐藏某些信息,则有一些模式(Crockford sealer Unceller应产生可用的结果)

这里所说的是一个快速修复对象的尝试:

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
函数BaseAAR{

this._arr=[];//注意>this您永远不会调用
new BaseARR()
任何地方。如果你想使用该构造函数获得新对象,你需要使用
new
关键字。哇,你是用JavaScript编写Java的完美例子。你在
\u arr
上缺少了一个
var
,这使它具有全局性。感谢这是JS中的一个大师级课程。我是一名自学成才的程序员,我认为自己是一名程序员广告开始理解JS。这个回复让我更加了解到底发生了什么。谢谢。我会阅读这些链接。我了解的越多,我就会理解的越多。
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