7

可能是我在这里遗漏了一些东西。请耐心等待,因为我是 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是指当前对象,我只是在这里对如何解决这个问题感到困惑。如果我错了,请纠正我。或者如果有更好的方法,那么我想知道它。

4

5 回答 5

3

您忘记使用new. IE 你有代码child(...)而不是new child(...)

一些技巧:

  • 不要new用于链接原型,只是做Child.prototype = Object.create(Parent.prototype)
于 2013-06-20T16:30:19.723 回答
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

错误解释

函数 withnew从 javascript 中的函数创建构造函数。这意味着上下文成为函数本身。没有new(并且具有默认的非严格行为),上下文是全局上下文,因此您的错误

Object [object global] has no method 'someFunc'
于 2013-06-08T08:54:56.850 回答
2

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

您在这里使用了继承的组合形式。
Prototype Chaining(Implementation Inheritence) 以孩子的原型是父母的实例的方式 //somefunc() 实际上是以这种方式继承到孩子的原型而不是孩子的实例//

通过在子构造函数中调用父构造函数来窃取构造函数(经典继承)//没有以这种方式继承//

所以这里的问题是你遇到了一个几乎每个初学者在使用组合继承时都会遇到的问题。问题是

在组合继承中,我们两次调用 SuperType(parent)。曾经通过经典继承和其他通过使 child.prototype 成为 parent 的实例您从经典继承(即从子构造函数中)进行了第一次调用。直到此时您还没有创建 child.prototype 作为父对象的实例并且您正在使用 this.someFunc() 通过原型继承分配给子实例。这是错误的原因。

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

简而言之,我的意思是

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

更好的解决方案是使用寄生组合继承,其中父对象仅被经典继承调用一次。

于 2013-06-10T08:30:19.190 回答
1

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

parent.method.call(this)
于 2013-06-08T07:47:08.943 回答
1

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

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

可以在此处找到有关 JS 原型如何工作的基本解释:原型继承 - 编写

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

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);
于 2013-06-08T08:06:35.897 回答