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

时间:2013-06-08 07:37:39

标签: 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();

当我这样做时,它有效。

var obj = new child();
obj.someFunc();

但是我希望在下面的子项中有someFunc(),

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

这样做会给我一个错误Uncaught TypeError: Object [object global] has no method 'getLightBox'但是据我所知this指的是当前对象,我只是在这里混淆了如何解决这个问题。如果我错了,请纠正我。或者,如果有更好的方法,那么我想了解它。

5 个答案:

答案 0 :(得分:3)

您忘记使用new。 I.E.你有代码child(...)代替new child(...)

一些提示:

另外

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

答案 1 :(得分:2)

首选解决方案

Javascript OOP在上下文处理中是特定的:如果您的父级使用上下文( this ),只需使用其上下文调用子级中的父级(请注意 new function(),用于设置从全局到新创建的对象的上下文:

var parent = function() { // constructor, should be called with new
  this.someFunc = function() { return "a string"; }
}

var child = new function() { // object, was already called with new
  parent.call(this); // set parent context to child's, don't create new one
  var someVal = this.someFunc(); // method from parent.
}

console.log(child.someFunc()); // a string

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

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

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

与您的工作示例相比

您也可以使用标准 prototype将原型设置为构造函数,而不是对象。请注意,在设置原型后创建对象,查看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中从函数创建构造函数。这意味着上下文成为函数本身。没有new(并且具有默认的非严格行为),上下文是全局上下文,因此您的错误

Object [object global] has no method 'someFunc'

答案 2 :(得分:2)

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

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

构造函数Stealing(Classical Inheritence)通过在Child Constructor中调用Parent构造函数//没有以这种方式继承//

所以这里的问题是你遇到了几乎每个初学者都使用Combined Inheritence的问题。 问题是

在组合的Inheritence中,我们两次调用SuperType(parent)。一次通过经典的继承和其他使child.prototype成为父实例 你从经典继承(即从子构造函数中)开始第一次调用。这次你没有创建child.prototype作为实例 父对象和你正在使用this.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>

更好的解决方案是使用Parasitic Combination Inheritence,其中父对象只被调用一次 通过经典的继承。

答案 3 :(得分:1)

确保你试图调用的函数是在父对象的原型上,而不是在它自己的对象上(类方法vs“静态”方法)如果方法是“静态的”你不能在它中调用它有这个但有

的儿童班
parent.method.call(this)

答案 4 :(得分:1)

我不确定你期望的是什么,但如果你想将someVal作为Child的一个属性并在创建实例后被访问,那么你应该使用this.someVal而不是var someVal声明它。

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

可以在此处找到有关JS原型如何工作的基本说明:Prototypical inheritance - writing up

您提供的代码应该没有问题:

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);