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?
-
1Would it be accurate to say you want to define "private-like" fields in your JS Object?Y123– Y1232015年04月23日 23:04:32 +00:00Commented Apr 23, 2015 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– Andrew Berg2015年04月23日 23:31:31 +00:00Commented Apr 23, 2015 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.user400654– user4006542015年04月24日 15:21:05 +00:00Commented Apr 24, 2015 at 15:21
-
I agree, it's just making me a little crazy that I might be missing something.Andrew Berg– Andrew Berg2015年04月24日 18:04:50 +00:00Commented Apr 24, 2015 at 18:04
1 Answer 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– Andrew Berg2015年04月24日 13:40:54 +00:00Commented Apr 24, 2015 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– Philipp2015年04月24日 13:44:13 +00:00Commented Apr 24, 2015 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– Andrew Berg2015年04月24日 13:59:58 +00:00Commented Apr 24, 2015 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– Jimmy Breck-McKye2015年05月24日 11:40:39 +00:00Commented May 24, 2015 at 11:40