JavaScript 从子对象调用父函数
JavaScript call parent function from child object
我是javascript面向对象编程的新手。并尝试实现我们从其他编程语言中知道的基础知识。
我有两个班级,一个家长和一个孩子。父母有一些私人功能和一些公共功能。子类将继承父类。
我希望从子对象访问父公共函数。我想做什么:
function SuperClass {
//Constructor implementation of this class
//public functions
return {
parentPublicFunction: function() {
//Public function implementation
}
}
function privateFunction() {
//Private function implementation.
}
}
//Inheriting
childClass.prototype = Object.create(SuperClass.prototype);
childClass.prototype.constructor = childClass;
childClass.prototype.parent = SuperClass.prototype;
function childClass {
//Call to super constructor
this.parent.constructor.call(this, arguments);
//Public function for childClass.
return {
childPublicFunction: function() {
//function implementation
}
}
}
var childObj = new childClass();
childObj.parentPublicFunction();
运行此程序时出现此错误:
未捕获的类型错误:未定义不是函数
我是否在做不正确的事情。?提前感谢!
JavaScript OOP不像Java或C#那样工作,不要指望它,也不要试图做到这一点。这样做唯一会导致误解。与其试图将你的旧范式强加于一种完全不同的语言,不如学习JavaScript OOP是如何工作的。
JavaScript是面向对象的,但这并不意味着它有类。至少不是大多数来自Java或类似语言的开发人员对类的看法。它也没有经典继承。但是,所有这些都可以"伪造"或模仿(这是您实际上试图做的事情)。这样做的问题在于,来自Java或类似语言的开发人员看到的代码看起来像类和经典继承,所以他们认为它是具有经典继承的类,并期望它表现得如此,而它最终可能会完全不同。
让我们从您的SuperClass
函数开始(因为它就是这样。它是一个函数,而不是一个类)。首先,你的代码甚至不是有效的语法,因为你的SuperClass
函数没有括号。正确的语法是 function SuperClass() { ... }
.
其次,JavaScript 使用原型来处理对象(而不是类)之间的继承,如果你想做原型继承(你的一些代码建议你想要这样做),你不能从 SuperClass
函数返回一个新的匿名对象。请允许我稍微说明一下这里的情况。
当您使用 new
关键字调用 SuperClass
函数(从 childClass
函数或任何其他位置)时,如 var inst = new SuperClass();
中所示,实际发生的情况如下:
- JavaScript 创建一个新的空白对象,该原型等于您正在调用的函数上的
prototype
-属性。在代码中,这将var temp = Object.create(SuperClass.prototype);
. - JavaScript 使用该对象作为
this
对象调用您的函数。在代码中,这将SuperClass.call(temp, <arguments>)
. - 如果函数返回任何内容,则
inst
设置为该值,否则,它将设置为temp
值。
现在,在SuperClass
函数中执行以下操作:
//Constructor implementation of this class
//public functions
return {
parentPublicFunction: function() {
//Public function implementation
}
}
function privateFunction() {
//Private function implementation.
}
这里发生的事情是,你的SuperClass
方法get被调用this
,这是SuperClass
的一个实例,即它在原型链中具有SuperClass.prototype
。这意味着,例如,如果你做this instanceof SuperClass
,你会得到true
,正如你所期望的那样。然后你返回一个新的匿名对象,它有一个名为 parentPublicFunction
的属性(它恰好是一个函数,但可以是任何东西)。您返回的这个新对象不是 SuperClass
的实例。它的财产中没有SuperClass.prototype
。你创造了一种情况,如果我这样做(new SuperClass()) instanceof SuperClass
你就会得到错误。换句话说,您从SuperClass
构造函数返回的实例不会实现您的"类"。这可能根本不是你的意图,这就是为什么你不能只在 JavaScript 上绑定经典继承原则并期望事情运行相同的原因之一。
现在,到目前为止,我们得到的是一个函数名称 SuperClass
,它返回一个与SuperClass
没有任何关系的Object
。 SuperClass
有一个空的原型,这意味着即使您以某种方式设法在其原型链中创建了带有SuperClass.prototype
的对象,它也不会从SuperClass
继承任何东西,因为没有定义要继承的内容。这就把我们带到了childClass
函数。
首先,我将它命名为ChildClass
而不是childClass
。JavaScript 中您希望人们使用 new
调用的任何函数都应该以大写字母开头。任何不希望用new
调用的函数都应该以小写字母开头。在JavaScript中没有办法知道一个函数是打算在有new
的情况下还是没有的情况下调用,所以这是用来表示的。
现在,ChildClass.prototype
被设置为SuperClass
的实例,这意味着SuperClass
原型中的任何方法都可以从ChildClass
的实例中调用。任何ChildClass
实例也是SuperClass
的实例(正如您所期望的那样)。但是,如前所述,SuperClass
的原型是空的,因此没有什么可以从中继承的。因此,ChildClass
从这种继承中获得的唯一好处是a instanceof ChildClass
暗示a instanceof SuperClass
.然而,就像SuperClass
一样,你从ChildClass
返回一个匿名对象,这再次导致(new ChildClass()) instanceof ChildClass
是假的事实。
其中,是你的(大部分)问题。解决方案只是学习OOP在JavaScript中是如何工作的,并在做JavaScript时接受它,而不是试图把它弯曲到你假设事情是如何工作的。
因为您要从构造函数返回自己的对象,所以您必须做更多的管道。
//Call to super constructor
this.parent.constructor.call(this, arguments);
返回 SuperClass
的公共 API,但您没有对结果执行任何操作。您必须将其合并到孩子的公共 API 中:
//Call to super constructor
var parentAPI = this.parent.constructor.call(this, arguments);
//Public function for childClass.
return Object.assign(parentAPI, {
childPublicFunction: function() {
//function implementation
}
});
分配给childClass.prototype
实际上与您无关紧要,因为您从构造函数返回的对象无论如何都不会从它继承。 即 childObj
不会具有您分配给原型的任何属性(例如 parent
)。返回自己的对象会错过更多的东西,例如能够使用instanceOf
(childObj instanceOf childClass
将被false
)。
使所有这些工作完成,您必须在构造函数中分配要this
的方法(而不是返回对象)。您可以在 MDN 文档中找到有关该 OOP 样式的更多信息。
注意:构造函数的名称通常以大写字母开头,即 ChildClass
.
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 在输入字段上有两个函数调用,一个在Blur上,一个不在Angular中
- 如何在Javascript函数调用中循环变量
- Javascript:应为赋值或函数调用,但实际看到的却是表达式
- 如何远程检查JavaScript应用程序的函数调用堆栈
- javascript函数调用不起作用
- 为什么这个函数调用会破坏程序并导致未定义的变量
- 如何通过函数调用设置图像的src
- 从全局函数调用Ember控制器上的方法
- 为什么Jquery$.ajax在函数调用中触发所有statusCode,即使调用成功
- JavaScript函数调用(arg1)(arg2)
- 打印链接时,将javascript函数调用到链接中
- 在函数调用中封装数据除了隐藏数据之外还有什么优点
- 无法从JavaScript中的函数调用对象属性
- 对中的函数调用进行排序是回调的唯一方法
- 函数调用方法有什么用
- Javascript:JSHint:应为赋值或函数调用,但实际看到的却是表达式
- HTML5(Bootstrap)通过函数调用运行动画
- 函数调用不起作用
- 函数中的Javascript函数调用