Object oriented programming in javascript

Object.create creates a new object, builds a prototype, all that screams reference. So, I’m not sure how you’d expect referenced primitive values in the prototype to be treated otherwise…? Maybe you’re making a confusion about passing values and prototype values.

And to be clear, Object.create does make a shallow copy. That’s why it’s useless for creating object state.

I’m not sure what you expect me to respond here. I never mentioned Object.create…

Almost everything is an object in JavaScript. Primitive types are not objects: strings, numbers, booleans. However, and this is where this almost comes from:

  • a wrapper object is created for these primitive values if there is a native method call on them;
  • even if the wrapper object is created, it’s temporary, so it can’t be used to attach properties to primitive values.

Yes, but it’s not out of the box. The module pattern, the revealing pattern are not out-of the-box solutions. There will be out-of-the-box support along with ECMAScript 6 which introduces classes sugar and the private keyword.

There is a prototype design pattern used in Java, which involves the clone concept, overwritten or not.

Actually, Java does precisely this with JIT. JIT takes bytecode and tries to improve performance by compiling it to native code at run time. But that’s the theory. In practice JIT returns both compiled to native and bytecode, because compiling it all to native would result in worse performance, not better.

And JavaScript may or may not produce bytecode. It could be directly translated to native code.

I don’t expect them to be treated differently. The point is this isn’t a clone.

To re-clarify, this is what I’ve been responding to:

" [JavaScript] uses object cloning to build new objects that inherit from other objects."

But when we build a new object that inherits from another object (aka Object.create), that’s not a clone we created. A clone is expected to be independent of the original (aka deep copy). But not only does Object.create not deep copy, it doesn’t even shallow copy. There’s no copying of any kind. That’s why changing even primitive values in the original affects the new object. And that’s why this isn’t a clone operation.

I believe you’re not understanding this quite well, object property vs. parameter or variable with a primitive value.

Object.create does a shallow copy for the properties, not for the values. If the property happens to be a primitive values, it’s still a property, it’s not a primitive value.

Changing the properties that are primitive values are universal because they belong in an object, and an object, as a whole, is shallow copied with Object.create.

Also, you’re hanging on too much on the strict meaning of the clone word. You could be thinking the same thing about the word prototype… :wink:

Prototyping definitely is object oriented, there’s no doubt about it. There have always been debates of whether class or prototype based languages are more object oriented than the other, its really up for your own interpretation. Still, not everyone gets used to Javascript’s OOP as its significantly different from what most of us were taught about object oriented programming in the very first place. Once a habit, its difficult to change. Its not javascript’s fault though.

Only if you consider object oriented to include both classical inheritance and prototypical inheritance. Most people when they consider what object oriented is only consider classical inheritance and there is a large difference between the two.

Crockford does. [URL=“https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/JavaScript_Overview”]MDN does. [URL=“http://www.ecma-international.org/ecma-262/5.1/#sec-4”]ECMAScript does. I don’t mean to harp, but… this is pretty clear cut.

The point I have been trying to make is that even if they are both considered to be object oriented there are greater differences between the two than there are between either and procedural code.

I suppose it’s like saying that 2 and 4 are both even numbers but 2 is closer to 1 than it is to 4. (where 1 is procedural, 2 is classical inheritance and 4 is prototypical inheritance).

Those who only know classical inheritance writing JavaScript generally write about three times as much code as they’d need to if they used the prototypical inheritance that JavaScript provides.

A name is only a name and even if you were to call procedural coding “object oriented” (which it obviously isn’t) it would still be closer to classical inheritance than prototypical inheritance is.

I can certainly understand that point. At first when you said prototypal inheritance wasn’t object oriented, I assumed you just misspoke. That’s why I responded with just half a sentence and a silly emoticon. But then you insisted that prototypal inheritance (objects inheriting from other objects) wasn’t object oriented. But I suppose if it was just a miscommunication, then everything’s fine.

You have a point, true some OO features are only realizable with classical inheritance and I personally prefer programming languages that support classes and interfaces. Nonetheless, this does not mean prototypical inheritance is not object oriented. You are writing object oriented code so long as the following two criteria are met: 1) You are using objects in your code, 2) The design approach is object oriented.

Come to think about it, you definitely violate criterion 1 if you use procedural languages(although if your design approach is object oriented your code will look cleaner), while you may still violate criterion 2 even if you use Java, C# or Ruby when your code is poorly designed(a good example is to abuse the usage of static properties/methods). I personally consider them to be equally important to write true object oriented code, but some may weigh one criterion more than the other.

You can meet both criteria with Javascript and thus it is an object oriented or at least object based/capable language. In many purely object oriented languages(like smalltalk) classes themselves are objects, which indicate that class-based features are sufficient conditions for a programming language to be object oriented, but not the necessary conditions.

You can write procedural or classical inheritance object oriented or use prototypical inheritance (the most powerful of the three options) in JavaScript. You can’t use prototypical inheritance in Java or C# or Ruby etc - they only support the less powerful classical inheritance.

Just because you can write procedural code using a classical inheritance object oriented language doesn’t mean that it is a procedural language. Just because you can (by using a really convoluted approach that uses three times as much code as necessary) write classical inheritance in JavaScript doesn’t make it a classical inheritance object oriented language. It is a prototyping language - the object oriented features that have been mentioned are a small subset of what JavaScript can do just as procedural code is a subset of object oriented.

Calling JavaScript an object oriented language conceals the fact that it is far more powerful than most languages that go by that name. That’s why I tend to not refer to it as object oriented because it gives an impression that the language is a lot less powerful than it really is.

Tbh I dont really quite get what you are trying to say, are you arguing that Javascript’s OOP is more powerful than in other languages like Java, C# and Ruby? I dont really agree with it, Id say its just two different ways of approaching the problem. In fact, I personally prefer classical object oriented language structure, as prototype-based languages seem to make lots of things harder for me.

Class based object oriented gives you one way to define objects.

Prototype based object oriented gives you dozens of ways to define objects.

I suppose having only one way to do it does make things easier than having to decide if any of the dozens of other ways might make for more efficient code.

Anyway with ECMAScript 6 JavaScript is adding a class “wrapper” around one of the many ways it allows you to create objects so that you can write the code in a similar way in JavaScript to the way you would in any class based language provided that you are happy to create all of your objects using that one way and to ignore the situations where using any of the others might be the better approach.

Not too long ago, I was also of the opinion that prototypal inheritance is better than classical inheritance. After all, prototypal can emulate classical, plus more. But lately I’ve started to believe that the inheritance mechanism could be – and perhaps should be – a low-level implementation detail that we needn’t know or care about. And the ES6 class syntax was, in part, responsible for my change in thinking.

class Animal {
    constructor(name) {
        this.name = name;
    }
 
    sayName() {
        console.log(this.name);
    }
}
 
class Dog extends Animal { 
    bark() {
        console.log("Woof!");
    }
}

var spot = new Dog('Spot');

If the language used classical inheritance, then the result of the above would be just one object – the instance object – containing the accumulated properties and functions.

spot:
---------------------------
| name        | Spot      |
| constructor | *function |
| sayName     | *function |
| bark        | *function |
---------------------------

And if the language used prototypal inheritance (as JavaScript does), then the result would be a series of linked objects.

Animal:
---------------------------
| constructor | *function |
| sayName     | *function |
| __proto__   | *Object   |
---------------------------

Dog:
---------------------------
| bark        | *function |
| __proto__   | *Object   |
---------------------------

spot:
---------------------------
| name        | Spot      |
| __proto__   | *Object   |
---------------------------

That we can define and use objects in the same way regardless of the underlying inheritance mechanism makes me think that the inheritance mechanism isn’t as significant as we’ve made it out to be. We could architect our programs without knowing or caring exactly how the inheritance will be implemented.

Though, I did say earlier that prototypal can emulate classical plus more. In prototypal, since Animal and Dog are actually objects, that means we can alter and augment them during runtime. We can add new methods to their prototypes that will then be available to all descendant objects. But, to do so would almost certainly be bad practice, for the same reason that to alter or augment the built-in prototypes (Array, Date, etc) is also bad practice – because it can lead to unpredictable behavior. The exact same object could behave differently depending on if, and even when, its prototype is altered. That kind of unpredictability is bad. And if we choose to restrain ourselves from altering prototypes, then the feature set we’re left with is our emulation of classical inheritance.