3

我正在为我正在构建的许多应用程序设计一个 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() {}
});

当对象第一次在代码中定义时,它也有初始化的能力(单例使用这个)

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 中是否需要对类结构和类实例进行明确且受控的分离?将每个对象都视为实例有什么问题吗?

4

6 回答 6

4

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

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

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

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

于 2012-05-15T05:15:36.870 回答
2

所以我的问题是:在 javascript 中是否需要对类结构和类实例进行明确且受控的分离?将每个对象都视为实例有什么问题吗?

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

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

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

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

...当然,这new Base()也是您创建. Base所以你的系统非常相似。

同样,上面是一个草图,而不是一个完整的例子。一方面,通常你会看到构造和初始化是分开的,所以你不会真正看到用'sDerived.prototype = new Base()创建对象但没有实际调用的东西(稍后会这样做),但你明白了。诚然,该声明在某种程度上削弱了与您的系统的相似性,但我认为它根本不会破坏它。BaseprototypeBaseDerived

归根结底,这都是关于对象(实例)的,它们要么直接使用(你的),要么通过克隆或将它们设置为另一个对象的原型来sally间接地通过向其他对象提供特性(Person、 )来使用。Root

于 2012-05-15T05:11:51.190 回答
1

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

于 2012-05-15T05:11:44.453 回答
1

这就是我在 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");

希望它可以帮助

于 2012-05-15T05:44:10.063 回答
0

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

// 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();
于 2012-11-02T05:41:52.243 回答
0

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

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 = '';

}
于 2013-07-22T19:06:47.140 回答