如何在javascript中从子原型调用Parent类的构造函数方法?

时间:2016-02-07 10:37:53

标签: javascript inheritance

下面是代码片段,其中我在构造函数中定义了'run'方法,而不像原型中定义的'eat'方法。我怎样才能从继承自A1的B1原型中访问这个'run'方法。我的意图是覆盖B1中的'run'方法,我可以使用A1的现有'run'方法。有没有办法实现它?

function A1() {
	this.run = function() {
		return 'A1 runs';
	}
};
A1.prototype.eat = function() {
	return 'A1 eats';
};

function B1() {
	A1.call(this);
};
B1.prototype = Object.create(A1.prototype); //new A1();

B1.prototype.eat = function() {
	return A1.prototype.eat.call(this) + ',B1 also eats'; 
}

B1.prototype.run = function() {
	var parentRun = this.constructor.run();
	 var result = parentRun + ",B1 also runs";
	 return result; 
};


var b1 = new B1();
b1.eat(); // It will give 'A1 eats, B1 also eats', which is fine
b1.run(); // It will give 'A1 runs', where I want 'A1 runs, B1 also runs'.

编辑1: 我已经更新了代码片段,我已经删除了console.log并从每个方法返回了字符串。

最初我没有对此进行研究。有些人提到它是this的副本,我已经通过相同的链接,但我的问题完全不同。我知道如何调用父类的原型方法,我已经为“吃”做了。

我的查询很简单,
有没有办法访问Parent类的构造函数('run'方法)的方法,而不是原型方法('eat'方法)?

1 个答案:

答案 0 :(得分:3)

三个问题:

  1. run放置实例的A1不会返回任何内容,因此调用它会产生undefined

  2. A1run放在实例上,这意味着在您的b1实例中,B1.prototype.runrun隐藏了A1 this.constructor.run()直接分配给实例。

  3. A1不是您打算run版本的方式。

  4. 如果您将A1.prototype放在function A1() { } A1.prototype.eat = function() { console.log('A1 eats'); }; A1.prototype.run = function() { return 'A1 runs'; }; function B1() { A1.call(this); } B1.prototype = Object.create(A1.prototype); B1.prototype.run = function() { return A1.prototype.run.call(this) + ",B1 also runs"; }; var b1 = new B1(); console.log(b1.run()); 上,则可以执行此操作:

    class

    这很丑陋,这就是为什么I wrote a script to automate supercalls back in the day,但这就是你在这个级别工作时的表现。

    但是,现在,您使用的是ES2015的super语法和class A1 { eat() { console.log("A1 eats"); } run() { return "A1 runs"; } } class B1 extends A1 { run() { return super.run() + ",B1 also runs"; } } var b1 = new B1(); console.log(b1.run()); ,而是使用BabelTraceur进行转换,或者在必要时使用相似内容来支持旧的JavaScript引擎:

    run

    Live copy on Babel's REPL

    重新编辑,说明希望A1成为原型,必须由function A1() { this.run = function() { return 'A1 runs'; }; } 分配,如下所示:

    run

    这有点麻烦,但你仍然可以做到。出于上述原因,在实例上设置B1.prototype.run会模糊您的实例通常使用的A1。所以要使用它,还要调用run非原型 B1,你必须在实例上替换它。

    出于这个原因,在run rathr中定义B1 B1.prototype比在A1上定义更合理,就像A1A1.prototype中定义它一样function B1() { var A1run; A1.call(this); A1run = this.run; this.run = function() { return A1run.call(this) + ",B1 also runs"; }; } ,而不是function A1() { this.run = function() { return 'A1 runs'; }; } A1.prototype.eat = function() { snippet.log('A1 eats'); }; function B1() { var A1run; A1.call(this); A1run = this.run; this.run = function() { return A1run.call(this) + ",B1 also runs"; }; } B1.prototype = Object.create(A1.prototype); var b1 = new B1(); snippet.log(b1.run());

    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

    实例:

    B1.prototype
    function B1() {
        var A1run;
        A1.call(this);
        A1run = this.run;
        this.run = function() {
          return A1run.call(this) + B1.prototype.run.call(this);
        };
    }
    // ...
    B1.prototype.run = function() {
        return ",B1 also runs";
    };
    

    但如果你真的,真的希望它(至少部分地)在function A1() { this.run = function() { return 'A1 runs'; }; } A1.prototype.eat = function() { snippet.log('A1 eats'); }; function B1() { var A1run; A1.call(this); A1run = this.run; this.run = function() { return A1run.call(this) + B1.prototype.run.call(this); }; } B1.prototype = Object.create(A1.prototype); B1.prototype.run = function() { return ",B1 also runs"; }; var b1 = new B1(); snippet.log(b1.run());上:

    <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
    <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

    实例:

    body{
        min-height:700px;
        min-width:900px;
        margin: 0;
        padding: 0;
        color: #000;
        font-family: Verdana, Arial, Helvetica, sans-serif;
        font-size: 100%;
        line-height: 1.4;
        background-color: #666;
        background-image: url(Images/backleave4.png);
        background-repeat: no-repeat;
        background-position: right top;
    }
    
     @media screen and (min-device-width: 481px) and (max-device-width: 800px)
    {
    .img-responsive {
    float: left;
    margin-left:4%;
    } 
    h4 {float: right;
    margin-right: 4%;
    margin-botttom: 2%;
    }
     p {
    float: right;
    margin-right: 4%;}
    }}