Javascript原型继承和OOP
Javascript prototypal inheritance and OOP
我正在创建一个允许用户创建小部件的应用程序。有几种不同类型的小部件,我使用原生继承定义了它们。即
//the base widget that all widgets inherit from
var Widget = function(){}
Widget.prototype.someFunction = function(){}
//widget type A
var A = function(){}
A.prototype = new Widget();
//widget type B
var B = function(){}
B.prototype = new Widget();
我发现在基类上添加一个方法会很方便,该方法可以创建相同类型的新小部件实例。即
//the base widget
var Widget = function(){};
Widget.prototype.clone = function(){
switch(this.type){
case 'A':
return new A();
break;
case 'B':
return new B();
break;
default:
break;
}
};
这将允许我使用以下代码获得相同类型的新小部件:
var widgetTypeA = new A();
var cloneOfWidgetTypeA = widgetTypeA.clone();
我担心的是,基础小部件现在必须明确地知道从它继承的每种类型的小部件。这是否违反了良好OOP的任何原则?
Widget.prototype.clone = function() {
var constructor = window[this.type];
return new constructor();
};
当然,假设所有的子类都被声明为全局类。
但老实说,我会在Widget命名空间中列出这些子类,并通过它访问它们,而不是使所有内容都全局化。
Widget.A = function(){};
Widget.A.prototype = new Widget();
Widget.prototype.clone = function() {
var constructor = Widget[this.type];
return new constructor();
};
假设您的构造函数是全局的,您可以执行以下操作:
var global = this;
Widget.prototype.clone = function() {
if (global[this.type])
return new global[this.type]();
};
假设每个实例都有一个类型属性,该属性的值是构造函数的名称。或者,您可以修复构造函数原型的构造函数属性,并执行以下操作:
Widget.prototype.clone = function() {
return new this.constructor();
};
function A() { };
A.prototype = new Widget();
A.prototype.constructor = A;
var a = new A();
var aa = a.clone();
然而,这是假设你没有任何参数要传递。如果你有参数要传递,那么你可能必须知道你正在生成哪种类型,所以无论如何都可以调用正确的构造函数。
如果支持ECMA5:
- 使用
Object.create(Object.getPrototypeOf(this));
如果ECMA5不受支持:
- 创建匿名函数
- 将匿名函数的原型设置为非标准属性
this.__proto__
示例:
var Widget = function() { };
Widget.prototype.clone = function() {
/*
Non-ECMA5:
var newClone = function() {};
newClone.prototype = this.__proto__;
return new newClone();
*/
// ECMA5
return Object.create(Object.getPrototypeOf(this));
}
var A = function() { };
A.prototype = new Widget();
A.prototype.name = "I'm an A";
var B = function() { };
B.prototype = new Widget();
B.prototype.name = "I'm a B";
var x1 = new A();
var y1 = x1.clone();
console.log("y1 should be A: %s", y1.name);
var x2 = new B();
var y2 = x2.clone();
console.log("y2 should be B: %s", y2.name);
您需要的信息已在constructor
属性中可用。但是,正如我最近在这里解释的那样,重写prototype
将丢失它。
使用我自己的ECMAScript版本3或版本5的类实现,您的示例如下:
var Widget = Class.extend({
someFunction : function() {
alert('someFunction executed');
},
clone : function() {
return new this.constructor;
}
});
var A = Widget.extend();
var B = Widget.extend({
constructor : function(arg) {
Widget.call(this); // call parent constructor
this.arg = arg;
},
// override someFunction()
someFunction : function() {
alert('someFunction executed, arg is ' + this.arg)
},
// clone() needs to be overriden as well:
// Widget's clone() doesn't know how to deal with constructor arguments
clone : function() {
return new this.constructor(this.arg);
}
});
var a = new A;
var a2 = a.clone();
a2.someFunction();
var b = new B(42);
var b2 = b.clone();
b2.someFunction();
相关文章:
- 从控制器继承了隔离的作用域以生成可重用的指令
- 两个指令创建新的继承的和隔离的作用域-元素得到哪个
- 当使用控制器作为语法时,如何从父指令继承属性
- 以jquery方式继承Javascript
- JavaScript对象不是从原型链继承的
- 使用Object.create()的角度服务继承
- 数据与Javascript中的继承冲突
- JavaScript对象继承问题
- 继承并重用对象oop
- Javascript OOP - 继承和原型设计
- Javascript OOP 继承了 create GLOBAL 对象
- Javascript OOP继承不起作用
- Javascript原型继承和OOP
- OOP意义上的jQuery/JavaScript类继承
- 如何在JetBrains Webstorm/PHPStorm中编写oop javascript(带继承)来获得自动完成/
- 把握“OOP"带有继承的模块模式
- OOP javascript对象继承(父/子)
- Javascript OOP和继承技术
- Javascript";OOP";以及具有多级继承的原型
- Javascript / Jquery OOP不继承属性