后代互相重叠
我创建了两个对象(Inherits),都从Base继承。 第二个对象的属性分配将覆盖第一个对象中的值。
有什么想法吗? 如何进行适当的继承,以便Base类将包含其继承后代的通用成员,但后代可以分配自己的值而不会相互干扰。
var testParams1 = { title: "john" };
var testParams2 = { title: "mike" };
Function.prototype.inheritsFrom = function (baseClass)
{
this.prototype = new baseClass;
this.prototype.constructor = this;
this.prototype.base = baseClass.prototype;
return this;
};
function Base() {
this.viewModel = {};
this.viewModel.title = (function ()
{
var savedVal = "";
return function (newVal)
{
if (typeof (newVal) === "undefined")
{
return savedVal;
}
savedVal = newVal;
};
})();
}
function Inherits(params) {
this.viewModel.title(params.title);
}
Inherits.inheritsFrom(Base);
///// preparing code:
var testObj1 = new Inherits(testParams1);
var testObj2 = new Inherits(testParams2);
///// testing code:
equals(testObj1.viewModel.title(), testParams1.title, "first instance ok"); // returns "john"
equals(testObj2.viewModel.title(), testParams2.title, "second instance ok"); // also returns "john"
问题)
Base
类的构造函数只被调用一次。 this.prototype = new baseClass;
this
对象跨实例,因为这些方法在构造函数(这被称为只有一次)中创建的。 基于意见问题的问题
Function.prototype
)。 解
Max的问题的最终解决方案
请特别注意inherits
函数和ParentClass.call(this, title);
线。 要查找的构造函数是ParentClass
和ChildClass
/**
* Allows a child constructor to safely inherit the parent constructors prototype chain.
* @type {Function}
* @param {!Function} childConstructor
* @param {!Function} parentConstructor
*/
function inherits(childConstructor, parentConstructor){
var TempConstructor = function(){};
TempConstructor.prototype = parentConstructor.prototype; // Inherit parent prototype chain
childConstructor.prototype = new TempConstructor(); // Create buffer object to prevent assignments directly to parent prototype reference.
childConstructor.prototype.constructor = childConstructor; // Reset the constructor property back the the child constructor
};
//////////////////////////////////////
/** @constructor */
function ParentClass(title) {
this.setTitle(title);
var randId_ = Math.random();
/** @return {number} */
this.getPrivlegedRandId = function()
{return randId_;};
};
/** @return {string} */
ParentClass.prototype.getTitle = function()
{return this.title_;};
/** @param {string} value */
ParentClass.prototype.setTitle = function(value)
{this.title_ = value;};
//////////////////////////////////////
/**
* @constructor
* @param {string} title
* @param {string} name
*/
ChildClass = function (name, title) {
ParentClass.call(this, title); // Call the parent class constructor with the required arguments
this.setName(name);
}
inherits(ChildClass, ParentClass); // Inherit the parent class prototype chain.
/** @return {string} */
ChildClass.prototype.getName = function()
{return this.name_;};
/** @param {string} value */
ChildClass.prototype.setName = function(value)
{this.name_ = value;};
放下兔子洞
对于那些想知道为什么这么做的人,简单地记住它的inherits
功能。
如何使用原型链解决属性问题
当在实例级别找不到属性时,JavaScript将尝试通过搜索实例构造函数原型链来解决缺失的属性。 如果在第一个原型对象中找不到该属性,它将搜索父级原型对象,直到Object.prototype
。 如果在Object.prototype
找不到它,则会抛出错误。
从子构造函数调用父构造函数:尝试#1
// Bad
var ChildConstructor = function(arg1, arg2, arg3){
var that = new ParentConstructor(this, arg1, arg2, arg3);
that.getArg1 = function(){return arg1};
return that;
}
使用new ChildConstructor
创建的任何变量都将返回ParentConstructor
的实例。 ChildConstructor.prototype
将不会被使用。
从子构造函数调用父构造函数:尝试#2
// Good
var ChildConstructor = function(arg1, arg2, arg3){
ParentConstructor.call(this, arg1, arg2, arg3);
}
现在构造函数和父构造函数被适当调用。 但是,只有在构造函数中定义的方法才会存在。 父原型上的属性将不会被使用,因为它们尚未链接到子构造函数原型。
继承父级原型:尝试#1
// Bad
ChildConstructor.prototype = new ParentConstructor();
取决于是否使用ParentConstructor.call(this)
,父构造函数将被调用一次或多次。
继承父原型尝试#2
// Bad
ChildConstructor.prototype = ParentConstructor.prototype;
尽管这在技术上是有效的,但对ChildConstructor.prototype
任何分配也将被分配给ParentConstructor.prototype
因为对象是通过引用传递而不是通过复制传递的。
继承父级原型尝试#3
// Almost there
var TempConstructor = function(){};
TempConstructor.prototype = ParentConstructor.prototype;
ChildConstructor.prototype = new TempConstructor();
这允许您将属性分配给ChildConstructor.prototype
因为它是临时匿名函数的一个实例。 在TempConstructor
的实例上TempConstructor
将检查它的属性的原型链,以便您成功继承了父原型。 唯一的问题是ChildConstructor.prototype.constructor
现在指向TempConstructor
。
继承父级原型尝试#4
// Good
var TempConstructor = function(){};
TempConstructor.prototype = ParentConstructor.prototype;
ChildConstructor.prototype = new TempConstructor();
ChildConstructor.prototype.constructor = ChildConstructor;
全部一起
var ParentConstructor = function(){
};
var ChildConstructor = function(){
ParentConstructor.call(this)
};
var TempConstructor = function(){};
TempConstructor.prototype = ParentConstructor.prototype;
ChildConstructor.prototype = new TempConstructor();
ChildConstructor.prototype.constructor = ChildConstructor;
您已成功从父类继承! 让我们看看我们能否做得更好。
继承函数
function inherits(childConstructor, parentConstructor){
var TempConstructor = function(){};
TempConstructor.prototype = parentConstructor.prototype; // Inherit parent prototype chain
childConstructor.prototype = new TempConstructor(); // Create buffer object to prevent assignments directly to parent prototype reference.
childConstructor.prototype.constructor = childConstructor; // Reset the constructor property back the the child constructor (currently set to TempConstructor )
};
var ParentConstructor = function(){
};
var ChildConstructor = function(){
ParentConstructor.call(this)
};
inherits(ChildConstructor, ParentConstructor);
链接地址: http://www.djcxy.com/p/5095.html
上一篇: descendants override each other
下一篇: Call a parent class's method from child class in Python?