1

我是 JavaScript 新手。在使用给定的javascript时,我期望输出值为“123”;“测试1”;“456”和“test2”,因为有两个实例。

但返回值为 "456";"test2"; “456”和“test2”。

如果我将设置器更改为处理“this”(目前已在代码中删除),问题就解决了。我无法理解为什么原型对象的行为不同。

我不想用这个声明变量,因为我希望变量是私有的,只能通过 getter/setters 方法访问。

<html>
<head>
<script type="text/javascript">

function Test(){
    var name;
    var id;


    Test.prototype.setId = function(newId){
        id = newId; 
    }

    //this.id = function(newId){
    Test.prototype.getId = function(newId){
        return  id;
    }


    Test.prototype.setName = function(newName){
        name = newName; 
    }

    //this.getName = function(newGuid){
    Test.prototype.getName = function(newGuid){
        return name;    
    }


}



function callme(){
    var instance1 = new Test();
    instance1.setId("123");
    instance1.setName("test1");
    var instance2 = new Test();
    instance2.setId("456");
    instance2.setName("test2");
    alert(instance1.getId());
    alert(instance1.getName());
    alert(instance2.getId());
    alert(instance2.getName());
}


</script>
</head>

<body>
<button onclick='callme()'> Test </button>
</body>
</html>

根据下面给出的 Matt 的建议,我已经更改了我的代码。但是代码不适用于继承。我修改了代码如下。当前实现创建派生类型的对象并尝试调用基类的方法。

<html>
<head>
<script type="text/javascript">

(function () {
    var stores = [];
    var counter = 0;
    Test = function () {
        this.storeId = stores.length;
        stores.push({});
    }

    Test.prototype.setGuid = function (newId) {
        stores[this.storeId].id = newId;
    }
    Test.prototype.getGuid = function (newId) {
        return stores[this.storeId].id;
    }
    Test.prototype.setName = function (newName) {
        stores[this.storeId].name = newName;
    }
    Test.prototype.getName = function (newGuid) {
        return stores[this.storeId].name;
    }
})();

Derived.prototype = new Test();
Derived.prototype.constructor = Derived

function Derived(){
    Test();//call to base class
    //some additional method
}


function callme(){
    var instance1 = new Derived();
    instance1.setGuid("123");
    instance1.setName("test1");

    var instance2 = new Derived();
    instance2.setGuid("456");
    instance2.setName("test2");

    alert(instance1.getName());
    alert(instance1.getGuid());

    alert(instance2.getName());
    alert(instance2.getGuid());



}


</script>
</head>

<body>
<button onclick='callme()'> Test </button>
</body>
</html>

stores其次,当变量被清除(超出范围)时,我不确定是否要从变量中清除内存。

4

3 回答 3

5

您的属性是全球性的。您必须使用this来引用实例的属性。

像这样修复您的代码:

function Test(){
    this.name =''; // this only to show that the property exist,
                   //  it doesn't change the behavior as you set it later
    this.id='';
}

Test.prototype.setId = function(newId){
    this.id = newId; 
}

Test.prototype.getId = function(){
    return this.id;
}


Test.prototype.setName = function(newName){
    this.name = newName; 
}

Test.prototype.getName = function(){
    return this.name;    
}

我修复了一些其他问题,其中包括你不应该声明一个参数,getX因为你不需要它。

于 2013-01-24T13:35:44.940 回答
1

每次创建新实例时都在设置原型方法 - 因此变量引用将在实例之间共享。

this.variableName按照dystroy的建议使用或使用this.setName = function(newName)。(将其用于变量会更好,因为它不会为每个对象实例复制函数。)

但是,如果您真的不想公开变量,请使用:

function Test(){
    var name;
    var id;

    this.setId = function(newId){
        id = newId; 
    }

    this.getId = function(newId){
        return  id;
    }

    this.setName = function(newName){
        name = newName; 
    }

    this.getName = function(newGuid){
        return name;    
    }
}

在不直接公开变量的情况下共享原型函数的解决方法是:

(function () {
    var stores = [];
    var counter = 0;
    window.Test = function () {
        this.storeId = stores.length;
        stores.push({});
    }

    Test.prototype.setId = function (newId) {
        stores[this.storeId].id = newId;
    }
    Test.prototype.getId = function (newId) {
        return stores[this.storeId].id;
    }
    Test.prototype.setName = function (newName) {
        stores[this.storeId].name = newName;
    }
    Test.prototype.getName = function (newGuid) {
        return stores[this.storeId].name;
    }
})();

说明:代码被包装在IIFE中,确保不能从该函数外部访问变量。在 IIFE 中,我们为我们的对象实例创建了一个存储列表。然后我们定义我们的Test类并将函数添加到原型中。

每当创建新实例时,我们都会创建一个新商店并将其附加到商店列表中。我们还将 a 添加storeId到实例中,以便我们可以访问实例存储中的值。外部函数可以访问 storeId,但可以从 store 本身获取任何数据。

stores[this.storeId]总是为我们的对象实例获取存储,然后我们使用类似于this.

于 2013-01-24T13:35:50.993 回答
0

我喜欢马特的方法。如果存储的数量变化很大,您可以使用对象而不是数组,并使用某种删除存储[this.storeID] 的 dispose 方法。也许 Javascript 中有一种方法可以在垃圾收集期间自动调用这样的方法/函数,或者当对象离开可用范围时?否则,您必须在为时已晚之前调用它。

继承问题可能是由错误实现的继承引起的。

于 2017-07-29T10:09:29.520 回答