我的情况与Web客户端界面有关,该界面应与其他硬件一起使用。它具有一个基本组件,并且基于连接的硬件进行了扩展(在此特定情况下,login()过程因设备而异)。
我通常是C ++开发人员,并且负责此JavaScript扩展,但我完全迷路了。
我要测试的场景:
Source1.js(可以说这是基本接口,所有硬件都一样):
function Login() {
this.type = 'login';
m_username = 'admin';
m_password = 'admin';
}
function Constructor() {
var mClass = new Login();
this.clicked = function() {
mClass.clicked();
}
this.getLogin = function() {
return mClass;
}
}
g_constructor = new Constructor();
Source2.js(此处应实现Login()。clicked()的功能):
function Login() {
this.clicked = function() {
document.getElementById("TextHere").innerHTML = m_username + ":" + m_password;
}
}
我测试过的HTML文件:
<html lang="en">
<head>
<title>JavaScript Test</title>
<meta charset="utf-8" />
<script src="source1.js"> </script>
<script src="source2.js"> </script>
</head>
<body>
<button onClick="g_constructor.clicked()">Test</button>
<p> </p>
<div id="TextHere">Text</div>
</body>
</html>
通常,我会使用诸如虚拟基类之类的东西,但是我完全不知道在JavaScript中该寻找什么。有人可以给我提示如何做这样的事情吗?每个Login()类型的对象都应具有Source2.js中给出的clicked()函数
答案 0 :(得分:1)
在JavaScript中,工作方式略有不同。使用原型对象创建对象。如果在原型对象上定义了方法,则可以使用实际的实现覆盖这些方法。
要在原型上定义方法,请勿将其定义为this
的属性。
// Code that could be in source file 1
function Login() {
this.type = 'login';
this.m_username = 'admin';
this.m_password = 'admin';
}
function Constructor() {}
Constructor.prototype = new Login();
Constructor.prototype.clicked = function () {
alert('You should implement the "clicked" method');
};
var g_constructor = new Constructor();
// Code that could be in source file 2
Constructor.prototype.clicked = function () {
document.getElementById("TextHere").innerHTML = this.m_username + ":" + this.m_password;
}
<button onClick="g_constructor.clicked()">Test</button>
<p> </p>
<div id="TextHere">Text</div>
您会注意到m_username
被定义为this
的属性,否则以后将不可用:在JS中为普通变量(当正确地用var
定义时)关键字)只能在定义它的函数范围内访问。
使用更现代的ES6语法(使用class
和extends
),看起来可能像这样:
// Code that could be in source file 1
class Login {
constructor() {
this.type = 'login';
this.m_username = 'admin';
this.m_password = 'admin';
}
}
class Constructor extends Login {
clicked () {
alert('You should implement the "clicked" method');
}
}
var g_constructor = new Constructor();
// Code that could be in source file 2
Constructor.prototype.clicked = function () {
document.getElementById("TextHere").innerHTML = this.m_username + ":" + this.m_password;
}
<button onClick="g_constructor.clicked()">Test</button>
<p> </p>
<div id="TextHere">Text</div>
注意:不必真正使用getLogin
方法,因为g_constructor
对象具有所有Login
成员。
答案 1 :(得分:0)
javascript与c ++不同,它不使用虚函数概念,而是可以使用composition,可以向这样的对象添加方法:
function A() {
this.virtualFunction();
}
A.prototype.virtualFunction = function() {
alert('A');
};
//-------------------------------------
function B() {
A.call(this);
}
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
B.prototype.virtualFunction = function() {
alert('B');
};
var b = new B();
PS ::这是我在另一个网站上找到的示例
答案 2 :(得分:0)
首先,将js功能分为多个文件是个坏主意,但是如果需要,可以更改现有类prototype
的{{1}}并在调用方法检查是否存在之前:
Login
:
source1.js
function Login() {
this.type = "login";
this._username = "admin";
this._password = "admin";
}
function Constructor() {
var mClass = new Login();
this.clicked = function() {
if (Object.getPrototypeOf(mClass).hasOwnProperty("clicked"))
mClass.clicked();
else
console.log("can't click :(");
}
this.getLogin = function() {
return mClass;
}
}
g_constructor = new Constructor();
:
source2.js
此外,如果您不想检查它,也可以在Login.prototype.clicked = function() {
document.getElementById("TextHere").innerHTML = this._username + ":" + this._password;
}
中放入空函数:
Login.clicked
并将其更改为第二个文件。