我想问一下以下OOP风格的优点。 我用以下方式编写JS类。
var MyClass = function() {
// private vars
var self = this,
_foo = 1,
_bar = "test";
// public vars
this.cool = true;
// private methods
var initialize = function(a, b) {
// initialize everything
};
var doSomething = function() {
var test = 34;
_foo = cool;
};
// public methods
this.startRequest = function() {
};
// call the constructor
initialize.apply(this, arguments);
};
var instance_1 = new MyClass();
var instance_2 = new MyClass("just", "testing");
这是一个好方法吗?有什么缺点吗? 我不使用继承,但它会以这种方式实现继承吗?
提前致谢。
答案 0 :(得分:6)
我认为这是一个非常好的方法。不要为“无遗产”问题感到羞耻。大多数OOP不是关于继承。最重要的方面是封装和多态,你已经得到了它们。
可以说(好吧,我通常认为)继承只需要静态语言,你必须以某种方式告诉编译器这两种类型(类)是相关的,它们有一些共同点(共同的)祖先)这样它就可以允许多态性。使用动态语言OTOH,编译器不关心,运行时环境将找到没有任何继承的共性。
另一点:如果你在某些地方需要一些继承(例如在某些情况下很好,比如GUI),通常你会发现你可以轻松地在你的'简单之间进行互操作'对象/类,以及其他更复杂和更重的。 IOW:不要试图找到满足您所有需求的框架并将其用于一切;相反,只要它有助于解决具体问题,就可以使用你在每个时刻都更舒服的那个。
答案 1 :(得分:3)
我发现Douglas Crockford撰写的这些文章非常有用:
答案 2 :(得分:2)
实际上,这与Prototype.js(我最喜欢的库)通常做的方式并没有什么不同。如果你看这里:
var Class = (function() {
function subclass() {};
// All classes are created through Class.create( {/*JSON Object*/} );
// or Class.create( function, ...properties );
// The first form will create a unique class.
// The second form will create a Class which subclasses the initial function.
function create() {
var parent = null,
// $A just normalizes the array.
properties = $A(arguments);
// Which type of class definition was used?
if (Object.isFunction(properties[0]))
parent = properties.shift();
// This effectively creates a constructor
function klass() {
this.initialize.apply(this, arguments);
}
// Allows klass to have addMethods property
Object.extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
// Does this class have a parent class?
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
// Add methods to the class
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);
// emptyFunction = function(){};
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;
// Creates the constructor
klass.prototype.constructor = klass;
return klass;
}
function addMethods(source) {
// Does this class have a parent?
var ancestor = this.superclass && this.superclass.prototype;
// Grab the keys of a JSON object
var properties = Object.keys(source);
// Makes sure each object has a toString and valueOf method.
if (!Object.keys({ toString: true }).length) {
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
properties.push("valueOf");
}
//Loop through the properties.
for (var i = 0, length = properties.length; i < length; i++) {
// property is the Key in the JSON, value is the corresponding
// method or property value.
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames().first() == "$super") {
// Handles an override of a parent method.
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
// And here is the final value!
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();
上述优点是您可以快速轻松地管理继承。在你的情况下,如果没有像上面那样创建某种形式的外部帮助函数,继承(或者至少是覆盖函数)几乎是不可能的。
答案 3 :(得分:1)
我总是发现Douglas Crockford的网站是JavaScript最佳实践的宝贵资源。碰巧他写了几篇与你的问题有关的文章。
答案 4 :(得分:0)
如果您在JavaScript中寻找更基于类的继承结构,可能需要查看Dojo。
答案 5 :(得分:0)
您也可以使用文字和构建器。这样你就不必使用Javascript中那些不太吸引人的概念:prototype,new-statement和this-keyword。
基本配方很简单:
具有构建器的文字充当类。构建器函数充当构造函数,生成的文字充当类实例。
以下是一个例子:
Car = {
createNew:function() { //no prototype!
var obj = {};
var color;
obj.setColor = function(c) { color = c; }
obj.drive = function(){ alert('driving a '+color+' car'); }
return obj; //no this-keyword!
}
}
var car = Car.createNew(); //no new statement!
car.setColor('red');
car.drive();
可在此处找到更多文档:
http://www.gabordemooij.com/jsoop.html
在这里