这是非常广泛的,但有趣而详细。
我使用原型的标准JavaScript方法定义了两个“类”:
function Source() {
this._sourceGuid = "";
this._periodGuid = "";
this._eventName = "";
this._eventKind = 0;
if (arguments.length > 0) {
if (arguments[0].__proto__ === this.__proto__) {
this.sourceGuid(arguments[0].sourceGuid());
this.periodGuid(arguments[0].periodGuid());
this.eventName(arguments[0].eventName());
this.eventKind(arguments[0].eventKind());
} else {
this.sourceGuid(arguments[0].sourceGuid);
this.periodGuid(arguments[0].periodGuid);
this.eventName(arguments[0].eventName);
this.eventKind(arguments[0].eventKind);
}
}
};
Source.prototype.sourceGuid = function (value) {
if (arguments.length > 0) {
this._sourceGuid = value
} else {
return this._sourceGuid;
}
};
Source.prototype.periodGuid = function (value) {
if (arguments.length > 0) {
this._periodGuid = value
} else {
return this._periodGuid;
}
};
Source.prototype.eventName = function (value) {
if (arguments.length > 0) {
this._eventName = value
} else {
return this._eventName;
}
};
Source.prototype.eventKind = function (value) {
if (arguments.length > 0) {
this._eventKind = value
} else {
return this._eventKind;
}
};
Source.prototype.toJSON = function() {
return {
sourceGuid: this.sourceGuid(),
periodGuid: this.periodGuid(),
eventName: this.eventName(),
eventKind: this._eventKind()
};
};
function AnalogCamerasSource() {
this.__proto__.apply(this, arguments);
this._serverGuid = "";
this._cameraId = 0;
this._waitingTime = 0;
if (arguments.length > 0) {
if (arguments[0].__proto__ === this.__proto__) {
this.serverGuid(arguments[0].serverGuid());
this.cameraId(arguments[0].cameraId());
this.waitingTime(arguments[0].waitingTime());
} else {
this.serverGuid(arguments[0].serverGuid);
this.cameraId(arguments[0].cameraId);
this.waitingTime(arguments[0].waitingTime);
}
}
};
AnalogCamerasSource.prototype = Source;
AnalogCamerasSource.prototype.serverGuid = function (value) {
if (arguments.length > 0) {
this._serverGuid = value
} else {
return this._serverGuid;
}
};
AnalogCamerasSource.prototype.cameraId = function (value) {
if (arguments.length > 0) {
this._cameraId = value
} else {
return this._cameraId;
}
};
AnalogCamerasSource.prototype.waitingTime = function (value) {
if (arguments.length > 0) {
this._waitingTime = value
} else {
return this._waitingTime;
}
};
AnalogCamerasSource.prototype.toJSON = function() {
var json = this.__proto__.toJSON();
json.serverGuid = this.serverGuid();
json.cameraId = this.cameraId();
json.waitingTime = this.waitingTime();
return json;
};
现在我需要一个AnalogCamerasSource
的实例,我正在努力创建它:
var data = {"sourceGuid":"{05A00E05-F30D-497D-A272-156F135E1486}","periodGuid":"{8A071454-B473-4937-9C54-4899F866D7FA}","eventName":"signal-lost","eventKind":3,"serverGuid":"{9976B57D-486B-4BCA-8432-78D7C8EDB52B}","cameraId":4,"waitingTime":5};
var c = new AnalogCamerasSource(data);
现在,行this.__proto__.apply(this, arguments);
负责调用父的构造函数,它看起来应该没问题,但是现在它应该在父的构造函数中调用父函数,抛出以下错误:
TypeError: this.sourceGuid is not a function
at Function.Source (http://localhost:8081/js/app/events/model/0-Source.js:14:12)
at AnalogCamerasSource (http://localhost:8081/js/app/events/model/AnalogCamerasSource.js:3:33)
现在,这是来自Chrome调试器的图片,显示属性在this.__proto__.prototype
this.__proto__.apply(this, arguments)
AnalogCamerasSource
下{{1}}下方的原型链中。
那么,为什么this.sourceGuid不是函数?我该如何调用父的构造函数使这个链正常工作?
这是一个小提琴:https://jsfiddle.net/98bp8pvh/
答案 0 :(得分:1)
重构代码(避免在代码中使用__proto__
)
function Source() {
var args = arguments[0] || {};
this._sourceGuid = args.sourceGuid || '';
this._periodGuid = args.periodGuid || '';
this._eventName = args.eventName || '';
this._eventKind = args.eventKind || 0;
};
Source.prototype.sourceGuid = function(value) {
if (arguments.length > 0) {
this._sourceGuid = value || '';
} else {
return this._sourceGuid;
}
};
Source.prototype.periodGuid = function(value) {
if (arguments.length > 0) {
this._periodGuid = value || '';
} else {
return this._periodGuid;
}
};
Source.prototype.eventName = function(value) {
if (arguments.length > 0) {
this._eventName = value || '';
} else {
return this._eventName;
}
};
Source.prototype.eventKind = function(value) {
if (arguments.length > 0) {
this._eventKind = value || 0;
} else {
return this._eventKind;
}
};
Source.prototype.toJSON = function() {
return {
sourceGuid: this.sourceGuid(),
periodGuid: this.periodGuid(),
eventName: this.eventName(),
eventKind: this.eventKind()
};
};
function AnalogCamerasSource() {
var args = arguments[0] || {};
this._serverGuid = args.serverGuid || '';
this._cameraId = args.cameraId || 0;
this._waitingTime = args.waitingTime || 0;
this.sourceGuid(args.sourceGuid);
this.periodGuid(args.periodGuid);
this.eventName(args.eventName);
this.eventKind(args.eventKind);
};
AnalogCamerasSource.prototype = Object.create(Source.prototype);
AnalogCamerasSource.prototype.serverGuid = function(value) {
if (arguments.length > 0) {
this._serverGuid = value || '';
} else {
return this._serverGuid;
}
};
AnalogCamerasSource.prototype.cameraId = function(value) {
if (arguments.length > 0) {
this._cameraId = value || 0;
} else {
return this._cameraId;
}
};
AnalogCamerasSource.prototype.waitingTime = function(value) {
if (arguments.length > 0) {
this._waitingTime = value || 0;
} else {
return this._waitingTime;
}
};
AnalogCamerasSource.prototype.toJSON = function() {
var json = Source.prototype.toJSON.call(this);
json.serverGuid = this.serverGuid();
json.cameraId = this.cameraId();
json.waitingTime = this.waitingTime();
return json;
};
var data = {
"sourceGuid": "{05A00E05-F30D-497D-A272-156F135E1486}",
"periodGuid": "{8A071454-B473-4937-9C54-4899F866D7FA}",
"eventName": "signal-lost",
"eventKind": 3,
"serverGuid": "{9976B57D-486B-4BCA-8432-78D7C8EDB52B}",
"cameraId": 4,
"waitingTime": 5
};
var c = new AnalogCamerasSource(data);
console.log(c);
答案 1 :(得分:0)
我通过这种解决方法解决了我的问题,如果有人可以发布更正确的答案,我可以接受这是正确的答案:
我更改了原型定义:
AnalogCamerasSource.prototype = new Source();
然后我将以下功能添加到AnalogCamerasSource
:
AnalogCamerasSource.prototype.super = function() {
Source.apply(this, arguments);
};
然后在构造函数中我称之为:
function AnalogCamerasSource() {
this.super.apply(this, arguments);
...
};
像魅力一样。
答案 2 :(得分:0)
保持简单,做这样的继承:
AnalogCamerasSource.prototype = Source.prototype;
...只是apply
子类构造函数中父类的构造函数:
function AnalogCamerasSource() {
Source.apply(this, arguments);
...
}
通常无需直接引用__proto__
。
答案 3 :(得分:0)
尝试将AnalogCamerasSource.prototype = Source;
更改为AnalogCamerasSource.prototype = new Source;
,将this.__proto__.apply(this, arguments);
更改为Source.apply(this, arguments);
。
问题在于,您的方法AnalogCameraSource.prototype
设置为函数(Source对象的构造函数),而不是对象。此函数本身没有在其原型上定义的方法。如果您将AnalogCameraSource.prototype
设置为新的Source对象(使用new Source
创建),则AnalogCameraSource.prototype
是对象,这应该是应该的。这将在Source原型上定义的所有方法都放在AnalogCameraSource的原型链中,并且Source构造函数能够顺利运行。