Javascript原型继承 – 后代互相覆盖
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Javascript原型继承 – 后代互相覆盖,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6003字,纯文字阅读大概需要9分钟。
内容图文
![Javascript原型继承 – 后代互相覆盖](/upload/InfoBanner/zyjiaocheng/702/3e6c666266ab4819a2f4c908b7480902.jpg)
我正在创建两个对象(继承),都从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;
>特权方法将跨实例引用相同的此对象,因为这些方法是在构造函数中创建的(只调用一次).
基于意见问题的问题
>如果您计划与您不拥有的JavaScript一起工作,则应该尽量避免修改原生原型(即.Function.prototype).
解
>为每个创建的新实例调用构造函数和父构造函数.
>继承父原型链(不是父类的实例).
>保持创建的实例数与原型链中构造函数的调用数之比为1:1.
Max问题的最终解决方案
请特别注意继承函数和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;};
在兔子洞下
对于那些好奇的人,为什么这样做只需记住它的继承功能.
如何使用原型链解析属性
当在实例级别找不到属性时,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;
}
使用新的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实例上找不到的属性将检查它的属性的原型链,因此您已成功继承了父原型.唯一的问题是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);
内容总结
以上是互联网集市为您收集整理的Javascript原型继承 – 后代互相覆盖全部内容,希望文章能够帮你解决Javascript原型继承 – 后代互相覆盖所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。