adr*_*eld 5 javascript oop inheritance prototype
只是为了好奇,我在Javascript中玩原型继承和OOP继承.大多数结果涉及使用函数模拟"类"和"扩展"概念,而其他结果则使用原型和构造函数.
我写了这段代码:
function Warrior(weaponName) {
var weapon = weaponName;
this.getWeapon = function() {
return weapon;
};
this.setWeapon = function(value) {
weapon = value;
};
this.displayInfo = function() {
return {
"weapon": this.getWeapon(),
};
};
}
function Archer() {
var accuracy = "86%";
this.parent = Archer.prototype; // Inheritance workaround
this.getAccuracy = function() {
return accuracy;
};
this.setAccuracy = function(value) {
accuracy = value;
};
this.displayInfo = function() {
var form = this.parent.displayInfo();
form.accuracy = this.getAccuracy();
return form;
};
}
Archer.prototype = new Warrior("bow");
var w = new Warrior("sword");
var a = new Archer();
console.log(w.displayInfo());
console.log(a.displayInfo());
Run Code Online (Sandbox Code Playgroud)
我这样做是为了在显示来自Warrior类的信息时,它将对象显示为
{ weapon: "sword" }
Run Code Online (Sandbox Code Playgroud)
当显示来自Archer的信息时,对象是:
{ weapon: "sword", accuracy: "86%" }
Run Code Online (Sandbox Code Playgroud)
"子类"从"超类"中获取信息并添加到其中.从Archer调用"getWeapon()"或"setWeapon"也有效.即使我添加第三类"Kyudoka",扩展"Archer"并拥有它自己的属性,这个链也没有问题.
但是与我在研究时发现的更复杂的代码相比,我觉得这可能是一个天真的实现("继承工作方式"行),我缺少一些东西(考虑到JS有很多细微之处).
这是一个理论问题,我没有在任何系统中使用此代码.
根据《Javascript the Good Parts》一书的说法, javascript中的继承主要有3种:伪经典继承、原型继承和函数式继承。
您刚刚发布的内容适合伪经典继承,您可以在其中使用构造函数模拟类行为。
我发现函数式模式更有用、更灵活,它允许您保护变量(使它们私有)。
var constructor = function (spec, my) {
var that, other private instance variables;
my = my || {};
//Add shared variables and functions to my
that = a new object;
//Add privileged methods to that
return that;
}
Run Code Online (Sandbox Code Playgroud)
原型基本上是让您的对象直接从其他有用的对象继承,这就像将它们(有用的对象)作为您的新对象构造函数原型。
Object.beget = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
var a = {}
//Add shared variables to a
var b = Object.beget(a);
//Add new methods to b
Run Code Online (Sandbox Code Playgroud)
每个模式都有很多考虑因素,例如 Crockford 在他的书中说道“函数式模式具有很大的灵活性。它比伪经典模式需要更少的工作,并且为我们提供了更好的封装和信息隐藏以及对超级方法的访问”。,但我也看到过一些文章以相反的方式争论,例如这个http://bolinfest.com/javascript/inheritance.php
编辑 - - -
如果您可能想了解访问超级方法的不同方法,在功能模式中您可以执行以下操作:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function ( ) {
return method.apply(that, arguments);
};
});
var archer = function (spec, accuracy) {
var that = warrior(spec),
super_displayInfo = that.superior('displayInfo');
that.getAccuracy = function() {
return accuracy;
};
that.setAccuracy = function(value) {
accuracy = value;
};
that.displayInfo = function (n) {
var form = super_displayInfo()
form.accuracy = that.getAccuracy();
return form;
};
return that;
};
Run Code Online (Sandbox Code Playgroud)