JavaScript中的继承导致未捕获的TypeError

JavaScript中的继承导致未捕获的TypeError,javascript,oop,inheritance,Javascript,Oop,Inheritance,可能是我错过了什么。请容忍我,因为我是javascript中OOP的新手。但我需要找到解决我问题的办法 我有这个密码 var parent = function() {} parent.prototype.someFunc = function() { return "a string"; } 现在我尝试使用下面的代码继承父级 var child = function() { parent.call(this); } child.prototype = new parent();

可能是我错过了什么。请容忍我,因为我是javascript中OOP的新手。但我需要找到解决我问题的办法

我有这个密码

var parent = function() {}
parent.prototype.someFunc = function() {
  return "a string";
}
现在我尝试使用下面的代码继承父级

var child = function() {
    parent.call(this);
}
child.prototype = new parent();
var child = function() {
  parent.call(this);
  var someVal = this.someFunc(); // method from parent.
}
child.prototype = new parent();
当我喜欢这个的时候,它就起作用了

var obj = new child();
obj.someFunc();
但我想在孩子体内放一些func(),如下所示

var child = function() {
    parent.call(this);
}
child.prototype = new parent();
var child = function() {
  parent.call(this);
  var someVal = this.someFunc(); // method from parent.
}
child.prototype = new parent();

这样做会给我带来一个错误,因为
uncaughttypeerror:Object[Object global]没有方法“getLightBox”
,但据我所知
这个
指的是当前对象,我只是对如何解决这个问题感到困惑。如果我错了,请纠正我。或者如果有更好的方法,那么我想知道它。

确保您尝试调用的函数位于父对象的原型上,而不是对象本身(类方法与“静态”方法)如果该方法是“静态”的,您不能使用此方法在子类中调用它,但使用

parent.method.call(this)

我不确定您期望的是什么,但是如果您希望someVal是Child的属性,并且在创建实例后可以访问它,那么您应该使用this.someVal而不是var-someVal来声明它

在函数体中声明的用于创建带有var的对象实例的变量是个坏主意,因为这些变量仅在函数体中可用,而在原型函数中不可用

关于JS prototype如何工作的基本解释可以在这里找到:

您提供的代码应该可以正常工作:

var parent = function() {}
parent.prototype.someFunc = function() {
  return "a string";
}
var child = function() {
  parent.call(this);
  var someVal = this.someFunc(); // method from parent.
  console.log("someval in child body",someVal);
  this.publicProp=this.someFunc();
}
child.prototype = new parent();

var c = new child();
console.log("return value of someFunc",c.publicProp);

首选解决方案

Javascript OOP在上下文处理中是特定的:如果您的父对象使用上下文(this),只需使用其上下文调用子对象中的父对象(注意新函数(),它将上下文从全局设置为新创建的对象):

接近您的方法的非标准替代解决方案

如果设置父原型而不是使用其上下文,则可以使用非标准
\uuuuu proto\uuuu
成员,该成员可以访问其原型:

var parent = function() {} // constructor to create empty object
parent.prototype.someFunc = function() { // someFunc is in parent prototype
  return "a string";
}

var child = new function() {
  this.__proto__ = new parent(); // set prototype to parent with its own context
  var someVal = this.someFunc(); // method from parent.
}

console.log(child.someFunc()); // a string
与您的工作示例相比

您还可以使用标准
原型
将原型设置为构造函数,而不是对象。注意:对象是在原型设置后创建的,请参见
new
调用的位置,并将其与Felix Kling对问题的评论进行比较:

var parent = function() {}
parent.prototype.someFunc = function() {
  return "a string";
}

var child = function() { // no new here
  var someVal = this.someFunc();
}
child.prototype = new parent();

console.log((new child).someFunc()); // new moved here
已解释错误

带有
new
的函数从javascript中的函数创建构造函数。这意味着上下文成为函数本身。如果没有新的
(以及默认的非严格行为),则上下文是全局上下文,因此您会出错

Object [object global] has no method 'someFunc'

嘿,伙计,你的观念错了。 首先,您需要了解您在代码中所做的以下问题

您在这里使用了组合继承形式。
原型链接(实现继承)以子原型是父实例的方式//somefunc()实际上是以这种方式继承到子原型而不是子实例//

通过调用子构造函数中的父构造函数窃取构造函数(经典继承)////

所以这里的问题是你遇到了一个问题,几乎每个初学者都会遇到这个问题。 问题是

在组合继承中,我们两次调用超类型(父类型)。一次是通过经典继承,另一次是通过使child.prototype成为父实例 您从经典继承(即从子构造函数中)进行了第一次调用。到目前为止,您还没有创建child.prototype作为实例 父对象的实例和u正在使用通过原型继承分配给子对象实例的.someFunc()。这是错误的原因

解决方案:对父对象进行第一次调用,将子原型设置为父对象[child.prototype=new parent();]ans的实例,然后进行第二次调用 [正在创建子实例]

简言之,我是这个意思

<script>
var parent = function() {}
parent.prototype.someFunc = function() {
  return "a string";
}
var child = function() {
  parent.call(this);
  someVal = this.someFunc(); // method from parent.
}
child.prototype = new parent();
var obj = new child();

alert(someVal);
</script>

var parent=函数(){}
parent.prototype.someFunc=函数(){
返回“字符串”;
}
var child=function(){
家长。打电话(这个);
someVal=this.someFunc();//来自父级的方法。
}
child.prototype=新父级();
var obj=新的子对象();
警惕(某物);
更好的解决方案是使用寄生组合继承,其中父对象只被调用一次
通过传统继承。

您忘记使用
新的
。也就是说,您的代码是
child(…)
而不是
newchild(…)

一些提示:

  • 在中运行代码,这样忘记
    new
    将导致即时错误
  • 始终将构造函数名称大写,即
    Parent
    而不是
    Parent
    ,因此忘记
    new
    会像拇指酸痛一样突出。事实上
  • 始终为构造函数提供合理的名词名称,因为将名词作为函数调用是没有意义的,因此忘记
    new
    将再次像拇指酸痛一样突出

  • 不要使用
    new
    链接原型,只需执行
    Child.prototype=Object.create(Parent.prototype)

在firefoxworking中工作正常。。是的,工作很好,测试它并提供实例总是很好:@elclanrs你的例子解决了我的问题。谢谢,不要做
child.prototype=newparent()。此时不希望创建新实例。使用
child.prototype=Object.create(parent.prototype)取而代之。该错误似乎表明您在某个地方丢失了
new
。不,这不是关于子方法的变量,而是关于父方法的原型。我理解你所说的,但不是我要找的。@JJPA正如你在我更新的答案中看到的,你的代码应该可以毫无问题地运行。父母亲