Nodejs:三个函数打造Javascript的类模型
Nodejs:三个函数打造Javascript的类模型
Javascript是面向对象的语言,但遗憾的是没有提供现成的类模型。不过没关系,广泛使用的语言总能涌现出优美的诗句。下面就是实现Javascript类模型的三部曲:
1、属性扩展
GlobalNamespace.extend = function(to, from) {
to = to || {};
if (from) {
for (var property in from) {
var value = from[property];
if (value !== undefined) {
to[property] = value;
}
}
}
return to;
};
2、属性继承
GlobalNamespace.inherit = function(Child, Parent) {
var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F;
var i, l, o;
for(i=2, l=arguments.length; i<l; i++) {
o = arguments[i];
if(typeof o === "function") {
o = o.prototype;
}
GlobalNamespace.extend(Child.prototype, o);
}
};
3、基类工厂
GlobalNamespace.Class = function() { var len = arguments.length; var Parent = arguments[0]; var Proto = arguments[len-1];
var Child = typeof Proto.initialize == "function" ? Proto.initialize : function(){ Parent.apply(this, arguments); }; if (len > 1) { var newArgs = [Child, Parent].concat( Array.prototype.slice.call(arguments).slice(1, len-1), Proto ); GlobalNamespace.inherit.apply(null, newArgs); } else { Child.prototype = Proto; } return Child;
};
其中initialize是类的构造函数。
如此这般即可建立Javascript的类模型,例如:
定义基类
GlobalNamespace.BaseClass = GlobalNamespace.Class({ property: null,
initialize: function(p) { this.property = p || 'property'; }, getProperty: function() { return this.property; }
});
定义派生类
GlobalNamespace.SubClass = GlobalNamespace.Class({
setProperty: function(p) {
this.property = p || this.property;
}
});
创建实例
var base = new GlobalNamespace.BaseClass('abc');
console.log(base.getProperty()); // 'abc'
var sub = new GlobalNamespace.SubClass('opq');
console.log(sub.getProperty()); // 'opq'
sub.setProperty('xyz');
console.log(sub.getProperty()); // 'xyz'
参考文献:
【1】JavaScript: The Good Parts by Douglas Crockford. Copyright 2008 Yahoo! Inc., 978-0-596-51774-8
【2】http://trac.osgeo.org/openlayers/browser/trunk/openlayers/lib/OpenLayers/BaseTypes/Class.js
Nodejs:三个函数打造Javascript的类模型
JavaScript 是一门面向对象的语言,但它并没有直接提供类模型的概念。然而,通过一些巧妙的设计模式,我们可以用 JavaScript 实现一个类模型。以下是实现这一目标的三个核心函数:
1. 属性扩展
首先,我们需要一个函数来扩展对象的属性,以便我们能够将一个对象的属性复制到另一个对象中。
GlobalNamespace.extend = function(to, from) {
to = to || {};
if (from) {
for (var property in from) {
var value = from[property];
if (value !== undefined) {
to[property] = value;
}
}
}
return to;
};
这个函数接受两个参数 to
和 from
,它会把 from
中的所有属性复制到 to
中。
2. 属性继承
接下来,我们需要一个函数来实现属性的继承。这通常涉及到原型链的设置。
GlobalNamespace.inherit = function(Child, Parent) {
var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F;
var i, l, o;
for(i=2, l=arguments.length; i<l; i++) {
o = arguments[i];
if(typeof o === "function") {
o = o.prototype;
}
GlobalNamespace.extend(Child.prototype, o);
}
};
这个函数接受子类 Child
和父类 Parent
,并设置它们之间的原型链关系。此外,它还允许传递额外的对象来扩展子类的原型。
3. 基类工厂
最后,我们需要一个工厂函数来创建新的类。这个函数会处理类的初始化和继承逻辑。
GlobalNamespace.Class = function() {
var len = arguments.length;
var Parent = arguments[0];
var Proto = arguments[len-1];
var Child = typeof Proto.initialize == "function" ?
Proto.initialize :
function(){ Parent.apply(this, arguments); };
if (len > 1) {
var newArgs = [Child, Parent].concat(
Array.prototype.slice.call(arguments).slice(1, len-1),
Proto
);
GlobalNamespace.inherit.apply(null, newArgs);
} else {
Child.prototype = Proto;
}
return Child;
};
这个函数接受多个参数,其中第一个参数是父类(可选),最后一个参数是子类的原型对象。它会根据这些参数创建一个新的类,并返回这个类。
示例代码
下面我们来看一个具体的例子,如何使用这些函数来定义基类和派生类。
// 定义基类
GlobalNamespace.BaseClass = GlobalNamespace.Class({
property: null,
initialize: function(p) {
this.property = p || 'property';
},
getProperty: function() {
return this.property;
}
});
// 定义派生类
GlobalNamespace.SubClass = GlobalNamespace.Class({
setProperty: function(p) {
this.property = p || this.property;
}
});
// 创建实例
var base = new GlobalNamespace.BaseClass('abc');
console.log(base.getProperty()); // 'abc'
var sub = new GlobalNamespace.SubClass('opq');
console.log(sub.getProperty()); // 'opq'
sub.setProperty('xyz');
console.log(sub.getProperty()); // 'xyz'
在这个例子中,我们定义了一个基类 BaseClass
和一个派生类 SubClass
。通过调用 new
关键字,我们创建了这两个类的实例,并演示了它们的基本功能。
通过这三个函数,我们可以在 JavaScript 中实现一个简单的类模型,从而更好地组织和管理代码。
这个 感觉没必要吧?
好复杂
在Node.js中,虽然JavaScript本身并没有提供直接的类模型支持,但我们可以通过一些自定义函数来实现类似的功能。以下是基于您所提供的内容,使用三个核心函数来构建JavaScript类模型的方法。
属性扩展
用于将一个对象的属性复制到另一个对象上。
GlobalNamespace.extend = function(to, from) {
to = to || {};
if (from) {
for (let property in from) {
let value = from[property];
if (value !== undefined) {
to[property] = value;
}
}
}
return to;
};
属性继承
用于从父类向子类继承原型方法。
GlobalNamespace.inherit = function(Child, Parent) {
let F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F;
for (let i = 2, l = arguments.length; i < l; i++) {
let o = arguments[i];
if (typeof o === "function") {
o = o.prototype;
}
GlobalNamespace.extend(Child.prototype, o);
}
};
基类工厂
用于创建具有特定原型的类。
GlobalNamespace.Class = function() {
let len = arguments.length;
let Parent = arguments[0];
let Proto = arguments[len - 1];
let Child = typeof Proto.initialize == "function"
? Proto.initialize
: function() { Parent.apply(this, arguments); };
if (len > 1) {
let newArgs = [Child, Parent].concat(
Array.prototype.slice.call(arguments).slice(1, len - 1),
Proto
);
GlobalNamespace.inherit.apply(null, newArgs);
} else {
Child.prototype = Proto;
}
return Child;
};
使用示例
定义基类
GlobalNamespace.BaseClass = GlobalNamespace.Class({
property: null,
initialize: function(p) {
this.property = p || 'default';
},
getProperty: function() {
return this.property;
}
});
定义派生类
GlobalNamespace.SubClass = GlobalNamespace.Class(GlobalNamespace.BaseClass, {
setProperty: function(p) {
this.property = p || this.property;
}
});
创建实例
var base = new GlobalNamespace.BaseClass('abc');
console.log(base.getProperty()); // 'abc'
var sub = new GlobalNamespace.SubClass('def');
console.log(sub.getProperty()); // 'def'
sub.setProperty('ghi');
console.log(sub.getProperty()); // 'ghi'
通过这种方式,我们可以模拟出类似面向对象编程中的类模型功能,以便更好地组织和管理代码结构。