3

I have been playing with the Object creation outlined by Douglas Crockford in his new talk "The Better Parts"

function constructor(spec){
    var that = otherConstructor(spec),
        member,
        method = function(){
           // spec, member, method all available without using this
        };

     that.method = method;
     return that
}

In the code I'm working on I have a member value that I'd like to set in my object and my first instinct was to make that member public and simply change that value. When I asked Crockford the best way to do that (getter/setter vs that.property) he replied:

I covered that. You don't need public properties at all. Design at a higher level.

So I'm left wondering, what would be the higher level design?

If this is a simplified version of my object

animator = function(){
    var that = {},
        playbackSpeed;

    return that;
}

and my goal is to mutate playbackSpeed. My inclination is to add a public method setPlaybackSpeed. Is this what he means?

  • 1
    Would it be accurate to say you want to define "private-like" fields in your JS Object? – Yazad Apr 23 '15 at 23:04
  • Since I get privacy by default using this pattern, I'm trying to find right design for access to those private fields. Or if that's the right approach at all... – Andrew Berg Apr 23 '15 at 23:31
  • If the variable is private, and you want to keep it private, you'll need a setter. I don't understand why he would respond the way he did, unless there's some other option that I don't know about. If the var is private, you have to create a privileged function that can set/get it if that functionality is needed, otherwise you'll have to make it public. – Kevin B Apr 24 '15 at 15:21
  • I agree, it's just making me a little crazy that I might be missing something. – Andrew Berg Apr 24 '15 at 18:04
1

When you create an object with the new keyword, you have access to the this object which represents the "public" view of the object. Inside the scope of the function you also can create local variables which are then in the "private" scope. When you assign a function to a field of this and implement that function in the same scope, it can access any of your private variables. Here is an example:

function Animator (specs) {

    // private variable
    var playbackSpeed = specs.playbackSpeed; 

    // public method
    this.setPlaybackSpeed = function(speed) {
         // can access playbackSpeed because it is in the surrounding scope
         playbackSpeed = speed;
    }

}

var animator = new Animator( { playbackSpeed: 3.0 } );
  • Yes, I understand using constructors. But I'm specifically trying out a pattern that does not use them. – Andrew Berg Apr 24 '15 at 13:40
  • I don't think it is possible to have private variables without a constructor, because private variables need to be declared inside the scope of the constructor. – Philipp Apr 24 '15 at 13:44
  • Not just a constructor, any function invocation creates a private scope. eg: (function(){var foo="bar"}()); console.log(foo); // undefined – Andrew Berg Apr 24 '15 at 13:59
  • 1
    @AndrewBerg - avoiding constructors seems to be something of a fad in the JS world at the moment, and I'm not really sure it's warranted. Most of the reasons I've seen for it aren't terribly compelling. But whatever you do to create your objects, you are going to need a function if you want private state - only function closures provide lexical privacy in JavaScript. If you are reading a source that tells you to use e.g. prototypes exclusively and eschew private state completely, I would hint to you that not everyone who claims to state 'agreed best practices' actually does so. – Jimmy Breck-McKye May 24 '15 at 11:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.