我是JavaScript新手。在使用给定的javascript时,我期望输出值为“123”; “测试1”; “456”和“test2”,因为有两个实例。
但是返回的值是“456”;“test2”; “456”和“test2”。
如果我更改setter以处理“this”(目前在代码中已经出现),问题就解决了。我无法理解为什么protype对象表现得很差。
我不想用这个声明变量,因为我希望变量是私有的,只能通过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
变量清除内存。
答案 0 :(得分: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
中声明一个你不需要它的论点。
答案 1 :(得分:1)
每次创建新实例时都要设置原型方法 - 因此变量引用将跨实例共享。
根据破坏建议使用this.variableName
或使用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
类并将函数添加到原型中。
每当创建新实例时,我们都会创建一个新商店并将其附加到商店列表中。我们还向实例添加storeId
,以便我们可以访问实例存储中的值。外部函数可以访问storeId,但可以从商店本身获取任何数据。
stores[this.storeId]
总是为我们的对象实例提取商店,然后我们将其用于this
。
答案 2 :(得分:0)
我喜欢马特的做法。如果存储的数量发生了很大的变化,你可以使用一个对象而不是一个数组,并且有一种删除存储[this.storeID]的som类型的dispose方法。也许Javascript中有一种方法可以在垃圾收集过程中自动调用这样的方法/函数,或者当对象离开可用范围时?否则你必须在它为时已晚之前调用它。
继承问题可能是由错误实现的继承引起的。