javascript和node.js:oop
我的node.js结构与javascript oop有问题。我使用另一个类创建了一个类javascript和node.js:oop,javascript,arrays,node.js,oop,Javascript,Arrays,Node.js,Oop,我的node.js结构与javascript oop有问题。我使用另一个类创建了一个类 var base = function (name) { this.Rows = new Array(); }; var top = function (name) { this.name = name; }; top.prototype = new base(); var myClass = new top(""); myClass.Rows.push("a");
var base = function (name) {
this.Rows = new Array();
};
var top = function (name) {
this.name = name;
};
top.prototype = new base();
var myClass = new top("");
myClass.Rows.push("a");
console.log(myClass.Rows);
var myClass2 = new top("test");
myClass2.Rows.push("b");
console.log(myClass2.Rows);
此代码返回以下结果
[ 'a' ]
[ 'a', 'b' ]
但是我不必被算法作为这个代码的结果找到吗
[ 'a' ]
[ 'b' ]
谢谢你的帮助
解决:我解决了这个问题。重构代码
var base = function (name) {
this.Rows = new Array();
}
var top = function(name) {
top.prototype.constructor.call(this, name);
this.name = name;
}
top.prototype = Object.create(new base());
谢谢大家。这就是JavaScript原型继承的工作原理 对于语言新手来说,这似乎相当令人困惑:) 两个对象
myClass
和myClass2
具有相同的原型(在top.prototype=new base();
中设置)
这意味着当您访问它们的行
属性时,因为它们都没有属性,所以它们访问的是它们的原型。因为两者都是一样的,它们都作用在同一个物体上。如果添加行console.log(myClass2.Rows)代码>在代码末尾,它还将输出['a','b']
原型继承似乎让初学者感到困惑,因为在经典语言中,如果类A
扩展了类B
,那么A
的所有属性都被复制到B
——JavaScript中的情况并非如此
如果将代码重构为以下内容,则可以实现相同的功能:
var base = function () {
};
base.prototype.getRows = function(){
return this.rows;
}
var top = function (name) {
this.name = name;
this.rows= [];
};
top.prototype = new base();
var myClass = new top("");
myClass.getRows().push("a");
console.log(myClass.getRows());
var myClass2 = new top("test");
myClass2.getRows().push("b");
console.log(myClass2.getRows());
这将产生您期望的“经典”结果
然而,JavaScript的原型模型更关注于共享功能。我可能会将您的代码重构为:
var myClass = {Rows:[]},myClass2 = {Rows:[]};
是的,原型是共享的。我想你是有意这样继承的:
var base = function (name) {
this.Rows = new Array();
};
var top = function (name) {
base.call(this,name); // this replaces your prototype
this.name = name;
};
var myClass = new top("");
myClass.Rows.push("a");
console.log(myClass.Rows);
var myClass2 = new top("test");
myClass2.Rows.push("b");
console.log(myClass2.Rows);
调用会像调用方法一样调用函数,因此它会将对象设置为base
,然后使用特定属性覆盖它。正如nrabinowitz在评论中指出的,这不会继承任何原型方法
还有我最初的建议,我非常喜欢,但与上述建议相比没有任何好处:
var top = function (name) {
this.super=base; // these two lines replace your prototype
this.super(name);
this.name = name;
};
该方法将“base”变成一个成员函数,然后调用它。它将“top”设置为新的“base”对象,然后对其进行自定义。我选择“super”作为变量名,因为它类似于Objective C的样式。我希望创建新对象的结果集中的每一行。所以我想要的结果是正确的。var base=function(name){this.Rows=new Array();};//var top=function(name){//This.name=name;//};//top.prototype=新基();var myClass=新基数(“”);myClass.Rows.push(“a”);console.log(myClass.Rows);var myClass2=新基数(“”);myClass2.Rows.push(“b”);console.log(myClass2.Rows);这样的代码就是正确的结果。另一个类中的结果是错误的,该类已生成。@KiPSOFT我认为您的问题需要对JavaScript oop的工作原理有一点了解,如果您想更详细地讨论它的工作原理,欢迎您访问我想解释JavaScript oop设计工作原理的地方:):)我现在理解得更好了。你给上层阶级下定义了吗。所以我想产生不止一个类,我正在为每个类使用一个子类来重新定义Rows属性。在建议其他方法之前,我希望有一个实际的用例。如果您想了解更多关于JavaScript设计模式的信息,Addy Osmani有一本关于这个主题的好书。我发现在实践中,我很少求助于经典的oop子类化,因为没有它,我在JavaScript中获得了两个主要好处(多态性-JS是动态的,功能共享-原型)。可悲的是,构建可维护且正确的JavaScript代码超出了一个简单问题的范围:-)@KiPSOFT运气好吗?你最终做了什么?这是一个有趣的方法(尽管注意它不支持base
方法的原型继承,只支持构造函数设置)。更常见的JS习惯用法可能是使用base.call(this)
或base.apply(this,arguments)
(如果需要在构造函数之间使用公共参数)。我没有想到.call
,当然会更好(更快,更少的变量污染)。我会更新它,不过说实话我很喜欢“超级”风格!这很有趣:)。请注意,您提到的两行并没有替换原型(它仍然是对象)。更令人困惑的是,调用函数构造函数就像调用普通函数一样。我不推荐这种方法,因为它似乎违背了JavaScript的原型本质,但这是一个非常有趣的想法。我需要了解更多的javascript:)@BenjaminGruenbaum:我已经用关于原型的注释更新了它(我不经常使用原型,所以我没有考虑过)。但是,当不需要Base的原型时,我认为这种方法没有问题,而且肯定比我见过的任何其他方法都简单、直观。这是一个很好的起点: