简体   繁体   中英

Why to use class based OOP style inheritance in javascript?

If I'm not completely wrong every framework/library/approach in javascript tends today to mimick class based OOP style inheritance. Reasons for this seem to be people thinking class based OOP inheritance is far easier to understand and that most programmers know OOP.

In my experience I don't find evidence for either of this opinions. I think javascript prototypal inheritance is just fine (and I doubt the usefulness to force another paradigm upon a language than the one it is built on). Most of the developers I meet aren't even that good in classical OOP either. So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?

I think the answer is in your question - most programmers are far more familiar with class-based OOP than prototype-based.

In fact I'd go so far as to say the majority don't believe you can have objects without classes.

note that even if you're arguing for prototype-based OOP, you call it 'prototypal', and class-based OOP just 'OOP'. so, you yourself suffer from this bias, thinking OOP=>classes, prototypes => something else.

and since most people think that OOP is the right way no matter the problem, then prototypes must be inferior.

so, to answer your question, it's two factors:

  1. a bad definition: "OOP => classes"
    • propaganda: "it must be OOP, or you're not worthy"

since you're still bounded by the first, you try to explain that prototypes are an exception of the second. much easier is to correct them:

  1. there are many ways to do objects, classes are just the easiest one for static languages. most people are taught to program with static languages, and most of them try to use any language just like the first one they learned.

    • there are many ways to structure a programming solution, OOP are great at some and lousy at others.

I feel as if you already know the answer to your question because you stated a part of it when you said

Reasons for this seem to be people thinking class based OOP inheritance is far easier to understand and that most programmers know OOP.

Neither paradigm is more right than the other for tackling a problem. I believe the main reason is that everyone is taught OOP through Java these days. So when people encounter OOP they think "oh classes" because it's what they are familiar with. And whenever they want to solve a problem they will most likely use what they know.

I would also state that it does no benefit for the programmer to use a paradigm he is unfamiliar with. Most of us must use javascript for client side web development and use a class based OOP language on the server. I personally would not want that OOP impedance mismatch whenever I had to look at the javascript side of an application.

At a certain level the fact that everyone is trying to implement class based OOP in javascript is an educational issue. At another level it's a psychological one.

So what are the reasons to choose classical OOP style inheritance over prototypal inheritance? Actually, I believe that some frameworks are "sort of" combining approaches. Take for example the Parasitic Combination Inheritance pattern. This is what YAHOO.lang.extend is doing.

It uses prototypal inheritance and a helper function to inherit prototypes and constructor stealing. Wow, that sounds complex...well yes it is - here's my implementation and test for example:

// Prototypal Inheritance
Object.prototype.inherit = function(p) {
    NewObj = function(){};
    NewObj.prototype = p;
    return new NewObj(); 
};

// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
    var prototype = Object.inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
};
function SubType(name, age) {
    Parent.call(this, name);
    this.age = age;    
};
inheritPrototype(SubType, Parent);  
SubType.prototype.getAge = function() {
    return this.age;
};

I have a test for this code:

   describe 'Parisitic Combination Inheritance'
 it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
     sub = new SubType("Nicholas Zakas", 29)
     sub.toString().should.match /.*Nicholas Zakas/
     sub.getAge().should.eql 29
     charlie = new SubType("Charlie Brown", 69)
     charlie.arr.should.eql([1,2,3])
     charlie.arr.push(999)
     charlie.arr.should.eql([1,2,3,999])
     sub.arr.should.eql([1,2,3]) 
     sub.should.be_an_instance_of SubType
     charlie.should.be_an_instance_of SubType
     (sub instanceof SubType).should.eql true 
     (sub instanceof Parent).should.eql true 
 end
    end

And of course, if you're paying attention to my literals you see: Nicholas Zakas, the guy I got this from ;) The big wins for this one: instanceof works (big deal some say and I kind of agree); instances don't share state on reference types like arrays (a biggie!); parent constructor only called once (a biggie!).

BTW, I have examples of most of the popular inheritance patterns here: My TDD JS Examples

For a long time I considered prototype-based OOP as weak, bad and wrong version of class-based OOP. Then, after a critical amount of information leaked into my head, I now understand OOP in more abstract way, and find both ways acceptable in general.

I'd argue that the language itself steers people into the classical mindset with it's choice of "new" as a keyword, and by introducing concepts like "constructors" in the language specification. In a way this is limiting - imagine the change in mindset if instead we had a clone keyword, and the concept of traits ala SELF.

When I was writing my first scripts, it was cool and handy to have such a simple language. But today you do not just want to toggle a buttoncolor, you want to build complex applications in JavaScript. Others might like to use your popular application and would love to see s community providing plugins.

Now, this is much easier to realize with OOP - especially because a lot of programmers a familiar with OOP concepts.

One reason may be that your server side is likely to be OO (ASP.NET, Java, etc.), so it's just easier to think in the same paradigm on the client. Not necessarily better , but easier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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