而不是纯粹的继承,在这里,我会使用原型扩展,除非你建立一些又大又丑的工厂,只是为了说“MovingPlatform”从“Platform”继承来纯粹意义上的,它不是你真正的会希望它是。
有一些问题(例如作弊),但如果您的对象完全基于this
,并且您对可能在控制台中入侵的人感到满意,那么您真的不必担心太多。
首先,了解你在里面做什么Platform
:
var MyObject = function (a) {
this.property = a;
this.method = function (b) { this.property += b; };
};
每次你创建一个新的MyObject
,你都在创建一个全新的.method
函数版本。
也就是说,如果你制作 10,000 个这样的函数,也会有 10,000 个该函数的副本。
有时这是一件非常好的和安全的事情。
这也可能是一件非常缓慢的事情。
问题是,因为对象中的所有内容都在 using this
,并且因为函数内部没有任何变化,所以创建新副本没有任何好处——只是使用了额外的内存。
...所以:
MyObject = function (a) {
this.property = a;
};
MyObject.prototype.method = function (b) { this.property += b; };
var o = new MyObject(1);
o.method(2);
o.property; //3
当您调用 时new X
,如果X
其原型上有属性/方法,则这些属性/方法会在其构造过程中被复制到对象上。
这和去是一样的:
var method = function (b) { this.property += b; },
o = new MyObject(1);
o.method = method;
o.method(2);
o.property; // 3
除非不需要自己动手做额外的工作。
这里的好处是每个对象都使用相同的功能。
他们基本上将功能访问权交给了他们的整体this
,并且该功能可以随心所欲地做任何事情。
有一个问题:
var OtherObj = function (a, b) {
var private_property = b,
private_method = function () { return private_property; };
this.public_property = a;
this.unshared_method = function () { var private_value = private_method(); return private_value; };
};
OtherObj.prototype.public_method = function () {
return private_property;
};
var obj = new OtherObj(1, "hidden");
obj.public_property; // 1
obj.unshared_method(); // "hidden"
obj.public_method(); // err -- private_property doesn't exist
因此,假设您不太关心保持私有性,那么最简单的方法是制作可重用的函数,该函数依赖于this
,然后您通过扩展将其提供给多个原型。
// collision-handling
var testCollision = function (target) { this./*...*/ },
handleCollision = function (obj) { this./* ... */ };
// movement-handling
var movePlatform = function (x, y, elapsed) { this.x += this.speed.x*elapsed; /*...*/ };
// not really the cleanest timestep implementation, but it'll do for examples
var Platform = function (texture, x, y, w, h) {
this.x = x;
// ...
},
MovingPlatform = function (texture, x, y, w, h, speedX, speedY, etc) {
this.etc = etc;//...
};
Platform.prototype.testCollision = testCollision;
Platform.prototype.handleCollision = handleCollision;
MovingPlatform.prototype. // both of the above, plus the movePlatform method
这是很多手工的。
这就是为什么不同库中的函数会clone
或extend
对象。
var bunchOfComponents = {
a : function () { },
b : 32,
c : { }
},
myObj = {};
copy(myObj, bunchOfComponents);
myObj.a();
myObj.b; //32
你的函数重用上升了,而手动编写适当的基于类的分层继承、虚拟覆盖、抽象和共享私有属性的恐惧下降了。