我希望在Javascript中简化继承。从我迄今为止收集的内容来看,实现"继承"在"类之间"如下:
function ParentClass() {
//Parent Constructor
}
ChildClass.prototype = new ParentClass(); //Step 1: Use parent as prototype
ChildClass.prototype.constructor = ChildClass; //Step 2: Designate appropriate constructor
function ChildClass() {
ParentClass.call(this, arguments); //Step 3: Call the parent's constructor from the child's
//Child Constructor
}
我喜欢把这个过程分成三个步骤"如上所述(步骤1,2和3)。我想将所有这三个步骤放在一个函数中(来自Java背景,我已将其标记为" extend"),我可以从函数构造函数对象调用,如下所示: / p>
function ParentClass() {
//Parent Constructor
}
ChildClass.extend(ParentClass); //Execute steps 1, 2 and 3 all in this function
function ChildClass() {
//Child Constructor
}
这是我到目前为止所做的:
Function.prototype.extend = function (parent) {
var oldConstructor = this.prototype.constructor;
this.prototype = new parent(); //Step 1
this.prototype.constructor = function (arguments) { //Step 2
parent.apply(this, arguments); //Step 3
oldConstructor(arguments);
};
}
扩展功能的第1步和第2步在此上下文中正常工作,但步骤3给了我一些问题。我试图做的是用一个新函数替换Child的构造函数,该函数调用父构造函数,然后调用Child的构造函数。但是当我运行它时,没有调用父构造函数。我还没有能够确定问题(我正在使用"这个"关键字正确吗?);也许我正以错误的方式接近这一点。有可能做一个这样做的功能,对吗?我该如何开展工作"扩展"功能
更新:
真正的问题似乎在于我使用"这个"关键词。这是我现在看的代码:
function ParentClass(x) {
this.value = x;
}
function ChildClass() {
}
ChildClass.extend(ParentClass);
function testtest() {
var a = new ParentClass("hello world"); //Alerts "hello world"
alert(a.value);
var b = new ChildClass("hello world"); //Alerts "undefined"
alert(b.value);
}
为什么第一个警报有效,第二个没有?我认为"这个"指的是函数运行的上下文,在两种情况下都是调用构造函数的对象(a或b)。
答案 0 :(得分:2)
如果你真的想这样做,也许你应该只使用Coffeescript。或者至少从中得到一些想法。
它在Javascript之上透明地提供support for classes and inheritance,并使用您在此处使用的几乎相同的想法来实现它。
如果这是一次学术练习,请务必继续(并查看Coffeescript如何为其提出建议)。但除此之外,没有必要重新发明轮子。
要进行直接比较,请将以下内容粘贴到http://js2coffee.org/
中class Shape
area: -> undefined
name: -> "Shape"
class Rectangle extends Shape
constructor: (w, h) ->
@w = w
@h = h
area: ->
@w * @h
name: -> "Rectangle" + super
矩形的name()
现在将返回RectangleShape
。名称是愚蠢的,但让你了解super
的工作原理。
JS中的内容(注意__extends
函数中的所有管道):
var Rectangle, Shape,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Shape = (function() {
function Shape() {}
Shape.prototype.area = function() {
return void 0;
};
Shape.prototype.name = function() {
return "Shape";
};
return Shape;
})();
Rectangle = (function(_super) {
__extends(Rectangle, _super);
function Rectangle(w, h) {
this.w = w;
this.h = h;
}
Rectangle.prototype.area = function() {
return this.w * this.h;
};
Rectangle.prototype.name = function() {
return "Rectangle" + Rectangle.__super__.name.apply(this, arguments);
};
return Rectangle;
})(Shape);
答案 1 :(得分:1)
注意到第二个块中的代码不执行相同顺序的步骤。在调用extend之后声明函数时,它会覆盖由extend函数创建的构造函数。首先尝试声明您的子类,然后扩展它:
这对我有用:
function Parent() {
console.log("Parent Constructor");
}
function Child() {
console.log("Child Constructor");
}
Child.extend(Parent);
new Child()
输出:
Parent Constructor
Child Constructor