了解 Javascript 中的类和继承 - 新模式

Understanding Classes and Inheritance in Javascript - New Pattern

本文关键字:新模式 模式 继承 Javascript 了解      更新时间:2023-09-26

我正在为我正在构建的许多应用程序设计OOP继承模式。 Javascript有很多方法可以做到这一点,但我偶然发现了一种我非常喜欢的模式。但是现在我正在努力解决类和实例分离的需求。

我有一个名为 Root 的基本对象。它有一个称为继承的主方法。创建您使用的新对象

var Person = Root.inherit({
    name : "",
    height : 0,
    walk : function() {},
    talk : function() {}
});

然后要创建一个"实例",您将

var sally = Person.inherit({
    name : "sally",
    height : "5'6"
});
Sally 可以 .talk((,她

可以 walk((,她有一个 .name 和一个 .height你可以用同样的方式让更多的人。

如果你想要一个构造函数,你使用

var Person = Root.inherit({
    _construct : function() {
        // do things when this object is inherited from
    },
    name : "",
    height : 0,
    walk : function() {},
    talk : function() {}
});

它还具有 init 的能力,当对象首次在代码中定义时(单例使用此(

var Person = Root.inherit({
    _init : function() {
        // called at runtime, NOT called if an object is inherited from me
    },
    name : "",
    height : 0,
    walk : function() {},
    talk : function() {}
});

如您所见,一切都使用 .inhert((。实际上没有类,也没有实例。一切都是某事的实例。到目前为止,我发现的唯一真正的问题是没有"类型"的概念,但是如果需要,您可以随时检查方法。此外,您不能保护"类",因为如果开发人员意外更改了"类",或者打算更改它,则可以在执行过程中更改"类"。

所以我的问题是:在javascript中是否需要对类结构和类的实例进行显式和受控的分离?将每个对象视为实例是否存在任何问题?

不,没有必要,因为Javascript是一种基于原型的语言,这意味着不涉及类。您只是在创建对象的克隆。

http://en.wikipedia.org/wiki/Prototype-based_programming

就类型的概念而言,类型是对象。

有关这方面的更多信息,一个很好的阅读是Stoyan Stefanov的Javascript模式,他有几种不同的创建模式来解决你的问题,包括从四人帮的设计模式中实现设计模式的示例。http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752

所以我的问题是:在javascript中是否需要对类结构和类的实例进行显式和受控的分离?将每个对象视为实例是否存在任何问题?

不是真的,如果你对它感到满意,那就好了。

更正常的 JavaScript 继承形式也做了同样的事情。你会经常看到这样的结构(为了简洁起见,严重削减了结构(:

function Base() {
}
Base.prototype.foo = function() {
};
function Derived() {
}
Derived.prototype = new Base();

。当然,new Base()也是您创建Base实例的方式。所以你的系统非常相似。

同样,以上是草图,而不是完整的示例。首先,通常你会看到构造和初始化是分开的,所以你不会从字面上看到Derived.prototype = new Base()的东西,就像创建一个具有Base prototype的对象但没有实际调用Base的东西(Derived稍后会这样做(,但你明白了。当然,这种说法在某种程度上削弱了与您的系统的相似性,但我认为它根本没有破坏它。

归根结底,这都是关于对象(实例(的,这些对象可以直接使用(您的sally(,也可以通过克隆或将它们设置为其他对象的原型来间接地为其他对象提供功能(PersonRoot(。

Javascript的继承是典型的,这意味着所有对象都是一个实例。您实际上必须做额外的工作才能获得经典继承。

这就是我在javascript中的工作方式

// this is class
function person(){
    // data is member variable 
     this.name = null;
     this.id = null;
    //member functions 
     this.set_name = _set_name;
     this.get_name = _get_name;
     this.set_id = _set_id;
     this.get_id = _get_id;
 function _set_name(name){
    this.name = name;
 } 
 function _get_name(name){
    return this.name;
 }
     function _set_id(id){
    this.id = id;
 } 
 function _get_id(id){
    return this.id;
 }
}
// this is instance
var yogs = new person();
    yogs.set_id(13);
    yogs.set_name("yogs");

希望它可能会有所帮助

从一些基本对象开始...

// javascript prototypes - callback example - javascript objects
function myDummyObject () {
    that = this;
} // end function myDummyObject ()
// begin dummy object's prototype
myDummyObject.prototype = {
    that : this,
    // add a simple command to our dummy object and load it with a callback entry
    say : function () {
        var that = this;
        console.log('speaking:');
        that.cb.run("doSay");
    }
} // end myDummyObject proto        

使用子原型扩展。

// here we addon the callback handler... universally self sufficient object
var cb = {
    that : this, // come to papa ( a link to parent object [ myDummyObject ] )
    jCallback : new Array(new Array()),     // initialize a javascript 2d array 
    jCallbackID : -1,                       // stores the last callback id
    add: function(targetFnc, newFunc) {
        var that = this;
        var whichID = that.jCallbackID++;
        // target, addon, active
        that.jCallback[that.jCallback.length] =  { 'targetFunc' : targetFnc,  'newFunc' : newFunc,  'active' : true, 'id': whichID };
        return whichID; // if we want to delete this later...      
    }, // end add
    run: function(targetFnc) {
        var that = this;
        for(i=0;i <= that.jCallback.length - 1;i++) // go through callback list
            if( that.jCallback[i]['targetFunc'] == targetFnc  && that.jCallback[i]['active'] == true )
                that.jCallback[i]['newFunc'](); // run callback.
    }, // end run
    remove: function (whichID) {
        var that = this;
        console.log('removing:' + whichID); 
        for(i=0;i <= that.jCallback.length - 1;i++) // go through callback list
            if( that.jCallback[i]['id'] == whichID  )
                that.jCallback[i]['newFunc'](); // run callback.
    } // end remove
}                                                               
// add the object to the dummy object...
myDummyObject.prototype.cb = cb;

例:

var testing = new myDummyObject();
testing.cb.add('doSay', function () { console.log('test: 213123123'); } );
// test remove...
var testid = testing.cb.add('doSay', function () { console.log('test: 12sad31'); } );
testing.cb.remove(testid);
testing.cb.add('doSay', function () { console.log('test: asdascccc'); } );
testing.cb.add('doSay', function () { console.log('test: qweqwe'); } );
testing.cb.add('doSay', function () { console.log('test: d121d21'); } );
testing.cb.add('doSay', function () { console.log('test: wwww'); } );

testing.say();

这对我来说似乎总是最容易理解的......只需创建继承类的新实例,然后遍历其变量和方法并将它们添加到主实例中。

var myPerson = new Person()
var myPerson.firstName = 'john';
var myPerson.lastName = 'smith';
var myPerson.jobTitle = 'Programmer';    
var Person = function(){
    //Use this to inherit classes 
    this._extendedClass = new Person_Job();
    for(var i in this._extendedClass){
        this[i] = this._extendedClass[i];
    }
    delete this._extendedClass;
    this.firstName = '';
    this.lastName = '';
}
var Person_Job = function() {
    this.jobTitle = '';
}