简体   繁体   English

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

[英]Understanding Classes and Inheritance in Javascript - New Pattern

I'm designing an OOP inheritance pattern for many applications I'm building. 我正在为我正在构建的许多应用程序设计OOP继承模式。 Javascript has many ways of doing this, but I stumbled on a pattern I really like. Javascript有很多方法可以做到这一点,但我偶然发现了一个我非常喜欢的模式。 But now I'm struggling with the need for a separation of classes and instances. 但是现在我正在努力解决类和实例分离的需要。

I have a base object called Root. 我有一个名为Root的基础对象。 And it has a main method called inherit. 它有一个名为inherit的主要方法。 To create a new object you use 要创建您使用的新对象

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

Then to create an "instance" you would 然后创建一个“实例”你会

var sally = Person.inherit({
    name : "sally",
    height : "5'6"
});

sally can .talk() and she can walk() and she has a .name and a .height You can make more people the same way. 莎莉可以.talk(),她可以走路(),她有一个.name和一个。你可以让更多的人以同样的方式。

If you want a constructor you use 如果你想要一个你使用的构造函数

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

It also has the ability to have init, when the object is first defined in code (singletons use this) 当代码首次在代码中定义时,它还具有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() {}
});

So as you can see, everything uses .inhert(). 所以你可以看到,一切都使用.inhert()。 There are no classes and no instances really. 没有类,也没有实例。 Everything is an instance of something. 一切都是事物的一个例子。 The only real problem I found so far is that there is no concept of "type", but you can always just check for a method if you need to. 到目前为止我发现的唯一真正的问题是没有“类型”的概念,但如果需要,你总是可以检查一个方法。 Also you can't protect a 'class', as a 'class' can be changed during execution if the developer accidentally changed it, or meant to change it. 此外,您无法保护“类”,因为如果开发人员意外更改了“类”,或者打算更改它,则可以在执行期间更改“类”。

So my question is: Is there a need in javascript to have an explicitly and controlled separation of class structure and instances of the class? 所以我的问题是:javascript中是否需要明确地控制类结构和类实例的分离? Are there any issues with treating every object as an instance? 将每个对象视为一个实例是否有任何问题?

No there's no need since Javascript is a Prototypal based language, meaning that classes are not involved. 不,没有必要,因为Javascript是基于Prototypal的语言,意味着不涉及类。 You are just creating clones of the objects. 您只是创建对象的克隆。

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

As far as the concept of type, the type is object. 就类型的概念而言,类型是对象。

A good read for more info about this would be Javascript Patterns by Stoyan Stefanov he has several different creational patterns that address your concerns, including examples that implement Design Patterns from the gang of four's design patterns. 有关这方面的更多信息的详细信息将是Stoyan Stefanov的Javascript模式,他有几种不同的创作模式可以解决您的问题,包括从四人组的设计模式实现设计模式的示例。 http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752 http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752

So my question is: Is there a need in javascript to have an explicitly and controlled separation of class structure and instances of the class? 所以我的问题是:javascript中是否需要明确地控制类结构和类实例的分离? Are there any issues with treating every object as an instance? 将每个对象视为一个实例是否有任何问题?

Not really, if you're happy with it, it's fine. 不是真的,如果你对它感到满意,那很好。

The more normal form of JavaScript inheritance does much the same thing. 更常见的JavaScript继承形式可以做同样的事情。 You'll frequently see structures like this ( severely cut down for brevity) : 你会经常看到像这样的结构(为了简洁而严重减少)

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

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

...and of course, new Base() is also how you create instances of Base . ...当然, new Base()也是您创建Base 实例的方式。 So your system is quite similar. 所以你的系统非常相似。

Again, the above is a sketch , not a full example. 同样,上面是草图 ,而不是一个完整的例子。 For one thing, usually you'd see construction and initialization separated out, so you don't literally see Derived.prototype = new Base() so much as something that creates an object with Base 's prototype but without actually calling Base (which Derived would do later), but you get the idea. 首先,通常你会看到构造和初始化分离出来,所以你不会直接看到Derived.prototype = new Base()就像使用Baseprototype创建一个对象但没有实际调用BaseDerived会在以后做,但你明白了。 Granted that statement somewhat weakens the similarity with your system, but I don't think it breaks it at all. 虽然这种说法有点削弱了与你的系统的相似性,但我认为它根本不会破坏它。

At the end of the day, it's all about objects (instances), which are either used directly (your sally ) or indirectly by providing features to other objects ( Person , Root ) by cloning or by setting them up as the prototype of the other object. 在一天结束时,它是关于对象(实例)的全部,它们可以直接使用(您的sally ),也可以通过克隆或通过将其设置为其他对象的原型来为其他对象( PersonRoot )提供功能。宾语。

Javascript's inheritance is prototypical which means everything object is an instance. Javascript的继承是原型的,这意味着所有对象都是一个实例。 You actually have to do extra work to get the classical inheritance. 你实际上必须做额外的工作来获得经典继承。

This is how I work in 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");

hope it may help 希望它可能有所帮助

Start with some basic object... 从一些基本对象开始......

// 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        

extend with a sub prototype.. 用子原型扩展..

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

Example: 例:

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();

This always seemed the easiest for me to understand... Just create a new instance of the inherited class and then loop through its variables and methods and add them to the main one. 这似乎对我来说似乎最容易理解......只需创建一个继承类的新实例,然后循环遍历其变量和方法并将它们添加到主类。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM