Nodejs:三个函数打造Javascript的类模型

发布于 1周前 作者 nodeper 来自 nodejs/Nestjs

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 &gt; 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


4 回复

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;
};

这个函数接受两个参数 tofrom,它会把 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'

通过这种方式,我们可以模拟出类似面向对象编程中的类模型功能,以便更好地组织和管理代码结构。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!