通过另一个源文件中的另一个函数扩展function()

时间:2018-07-14 13:36:35

标签: javascript

我的情况与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>&nbsp;</p>
        <div id="TextHere">Text</div>
    </body>
</html>

通常,我会使用诸如虚拟基类之类的东西,但是我完全不知道在JavaScript中该寻找什么。有人可以给我提示如何做这样的事情吗?每个Login()类型的对象都应具有Source2.js中给出的clicked()函数

3 个答案:

答案 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>&nbsp;</p>
<div id="TextHere">Text</div>

您会注意到m_username被定义为this的属性,否则以后将不可用:在JS中为普通变量(当正确地用var定义时)关键字)只能在定义它的函数范围内访问。

使用更现代的ES6语法(使用classextends),看起来可能像这样:

// 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>&nbsp;</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

并将其更改为第二个文件。