后代互相重叠
我创建了两个对象(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);
上一篇: descendants override each other
下一篇: Call a parent class's method from child class in Python?
