Javascript 构造函数原型-继承混淆
我首先定义两个独立的构造函数Javascript 构造函数原型-继承混淆,javascript,constructor,prototype,Javascript,Constructor,Prototype,我首先定义两个独立的构造函数 var Sword = function (attack,price){ this.attack = attack; this.price = price; }; var LegendarySword = function (){ this.instantKill = true; }; 这些构造函数创建的对象显然彼此不相关 var sword = new Sword(1, 100); console.log(sword); //Object at
var Sword = function (attack,price){
this.attack = attack;
this.price = price;
};
var LegendarySword = function (){
this.instantKill = true;
};
这些构造函数创建的对象显然彼此不相关
var sword = new Sword(1, 100);
console.log(sword);
//Object
attack: 1
price: 100
__proto__: Object
var superSword = new LegendarySword();
console.log(superSword);
//Object
instantKill: true
__proto__: Object
我现在希望所有的“类”传奇宝剑实例都具有剑“类”的特性,即攻击值和价格值。这是因为所有传说中的剑最终都是剑,但有一些独特的属性(比如“瞬间杀死”)
因此,在阅读了关于原型和继承的内容后,我发现我可以微笑着这样做:
LegendarySword.prototype = new Sword();
我理解这一行的方式是,在我构建LegendarySwarm类的新对象时,除了LegendarySwarm已有的构造函数之外,我还使用了Swarm的构造函数。我希望传说中的剑类物品获得攻击和价格属性,但同时我不希望剑类物品获得瞬杀属性
我还希望我现在能够在LegendarySwarm构造函数中提供参数:
var superSword2 = new LegendarySword (5, 1000);
我希望这会像剑构造器一样接受参数,但显然不是:
console.log(superSword2.attack); // results to undefined (which proves that it has them dug in somewhere in the __proto__, which is so indeed)
看起来我仍然可以从另一个角度解决问题。如果我在创建一个新的传奇宝剑对象时,不必要地使构造函数复杂化,向宝剑添加新方法,调用这些方法并传递参数:
var Sword = function (attack,price){
this.attack = attack;
this.price = price;
this.setAttack = function(attack){
this.attack = attack;
};
this.setPrice = function(price){
this.price = price;
};
};
var LegendarySword = function (attack, price){
this.instantKill = true;
this.setAttack(attack);
this.setPrice(price);
};
LegendarySword.prototype = new Sword();
var sword = new Sword(1, 100);
console.log(sword);// gives correct object attributes
var superSword = new LegendarySword(10,5000);
console.log(superSword); // gives correct object attributes
但这真的很难看,我的问题是为什么Javascript不能在我调整构造函数原型时发现需要添加新属性?这对我来说太直观了
是否有其他方法可以解决此问题?仅此而已
要解决您的问题,您只需执行以下操作:
var剑=功能(攻击、价格){
这个攻击=攻击;
这个价格=价格;
};
var legendarybrow=功能(攻击、价格){
this.instantKill=true;
剑。召唤(这个,攻击,价格)
};
var剑=新剑(1100);
控制台。日志(剑);//提供正确的对象属性
var superSword=新传奇宝剑(105000);
console.log(超级单词);//提供正确的对象属性
我希望这会像剑构造器一样接受参数,但显然不是:
console.log(superSword2.attack); // results to undefined (which proves that it has them dug in somewhere in the __proto__, which is so indeed)
您不应该期望,修改构造函数的原型不会修改构造函数本身
> console.log(superSword2.attack);
> // results to undefined
> // (which proves that it has them dug in somewhere in
> // the __proto__, which is so indeed)
这并不能证明这一点。您不知道该属性是否存在,因为访问不存在的属性也会返回undefined(这就是本例中实际发生的情况)
当您这样做时:
LegendarySword.prototype = new Sword();
您只需将Legendary剑的默认原型替换为剑的实例,它不会修改Legendary剑本身,因此构造函数不会添加攻击和价格属性
如果您希望Legendary剑的实例具有与剑相同的属性,可以执行以下操作:
var LegendarySword = function (attack, price){
// Add Sword properties
Sword.call(this, attack, price);
// Add LegendarySword properties
this.instantKill = true;
};
这将设置所需的原型链,并使用剑属性初始化Legendary剑。实际上可能有一种方法可以实现Child.prototype=Parent.prototype范式。关于这些方面,您怎么看:arguments.callee.prototype.constructor.apply(这是arguments);使用fiddle示例可能以下答案会有所帮助:它涵盖了构造函数和原型所扮演的角色,以及为什么创建父实例用作子实例是错误的。