javascript object properties vs public methods - javascript

If I have a javascript class in which I wish to expose a method, is it better to expose the method using the this keyword (ie to make it publicly accessible in an unqualified way either using this or object.prototype.method, or to define an object property using object.defineProperty?
I would like to know any performance implications that you might know about, including speed and/or footprint. Obviously in object.defineProperty, I have the ability to control access to the property, and thus to any method that it exposes, although I am limited to only one parameter per method. However, if use a method, then I can create the access control more flexibly, so encapsulation is not really an issue, but given that object.defineProperty is a language feature and allows me to use the revealing pattern, I wonder if there are any performance implications.
Many thanks for your input...

Related

Why is there a distinction between privileged and public methods? How to know which to use?

Why is there a distinction between privileged and public methods?
Why should I even bother with public methods, aren't privileged
methods more natural? They feel more intuitive as they allow access
to private methods and variables like in java.
Is there a specific reason behind this or was this an error in the
spec(got a little ahead of myself there!) or am I missing something?
In what situation would you use a public method over a privileged method?
here is the code to demonstrate:
var Foo = function(){
var privateVar = "i am private";
function privateFunc(){
console.log(privateVar);
}
this.privilegedFunc = function(){
privateFunc(); // can access
}
};
Foo.prototype.publicFunc = function(){
privateFunc(); // cannot access
};
var foo = new Foo();
foo.privilegedFunc(); // prints "i am private"
foo.publicFunc(); // Uncaught ReferenceError: privateFunc is not defined
it's just like any OOP language (without the visibility keywords though), if you need a method to be called outside the instance, public, else, private.
Functions that are not bound to this, cannot be accessed outside the scope because they are defined and declared in the scope of the constructor function.
And as per your latest comment, there are many reasons and scenarios where you will have to expose an objects function in order to be used by other objects e.g.
As per your comment in this answer, lets see some advantages of the prototype approach.
By using prototype, you are able to change a method and the change will reflect to all instances that share the same prototype, without the prototype, each instance will have it's own version of the given method, therefore you will have to change them one by one.
Another advantage, is performance, functions/methods declared in the prototype are only created once, whereas without the prototype, each time you use the new keyword to instantiate from a constructor function, all functions inside the constructor functions scope will have to be created.
It's important to note that there's no distinction in the spec between "privileged" and "public" methods (in fact I don't think the spec uses these terms at all - Douglas Crockford does), they are governed by the exact same rules, the most fundamental of which in play being function scope.
Note: I'll follow your terminology in my answer, but I actually recommend against it: more often you'll find people calling your privileged methods public, and your public methods prototype methods.
In your example, this.privilegedFunc has access to the private variable privateFunc because they are defined in the same scope - that is, the scope of the Foo constructor function. privilegedFunc will be able to use its reference to privateFunc even when called from "outside", via the so-called closure mechanism of the language.
To answer your questions directly:
Why is there a distinction between privileged and public methods?
There isn't a fundamental distinction. You defined two functions in different scopes, and as such, they can reference different variables.
Why should I even bother with public methods, aren't privileged methods more natural?
Natural is quite a subjective term. However, if you don't wish to expose fields directly, you need to use a privileged function to manipulate them from the outside.
They feel more intuitive as they allow access to private methods and variables like in java.
That intuition is based only on familiarity :) No wonder that when you try to use Javascript as Java, the parts which work differently in the two languages will seem the least intuitive. This doesn't mean that you should try to imitate the style you would use in either in the other, some solutions are better suited for Javascript, some better for Java.
Is there a specific reason behind this or was this an error in the spec or am I missing something?
(Such a fundamental error in the spec?! God no.) I'm not sure what you mean by "this", but the difference in visibility is explained by function scopes, see above.
In what situation would you use a public method over a privileged method?
For example, if you don't need to expose private fields via closures. An other noteworthy difference is that functions on the prototype will be shared (i.e. effectively the same function instance) amongst instances, while private and privileged methods will be unique to the instance, which can have an effect on memory footprint.
What you call "privileged" methods aren't part of the language syntax. Rather, it's a design pattern. It is possible due to the fact that javascript implement closures (the ability of functions to access the scope of an outer function even after that outer function has returned).
There is a theory that all languages that implement closures (or even just first-class functions) can implement an object system. Several functional languages took this approach when adding OO to the language: that OO features are not part of the language syntax but a library that you can use (or even write yourself). One of the prime examples of this is CLOS (Common Lisp Object System) in Lisp. It's a library that adds OO features to the language without needing to modify the language syntax.
As you have discovered, using a closure to access local variables does a good enough job to emulate the "feel" of private variables and public methods. This is a feature of closures - that you can create your own OO system without needing OO features.
The OO system in javascript was added because OO was a big deal then. Admittedly, if Brendan Eich didn't add OO to javascript we could have evolved a (or several) OO systems from scratch using pure javascript. Indeed, in the early 2000s people weren't comfortable with the prototypal object system in javascript and developed their own OO system to emulate what they were used to.
In javascript, the OO system has no concept of private methods or variables. This was deliberate. Several other languages share this philosophy that private members are a "mistake". The idea that privacy is bad practice was borne out of years of experience using libraries that made a feature you needed to access private. For languages that encourages open source or distribution of code that's not too big of an issue. You can always modify the library code to export what you want. But for languages that encourages distribution of libraries as compiled binaries that's a big issue. At the time javascript was created, most OO languages had features allowing you to distribute your libraries as compiled binaries. So there was a small backlash against the concept of privacy.
So.. when would you use a closure to emulate private variables? Use it when you really need something like a private variable.
Why is there a distinction between privileged and public methods?
I'm assuming you read Douglas Crockford website (this page). It's a distinction I haven't really seen used by other authors. I don't make that distinction, but I do know that the function has access to the constructor closure.
Why should I even bother with public methods, aren't privileged methods more natural? They feel more intuitive as they allow access to private methods and variables like in java.
They have a different meaning than public methods.
A) They are defined by the constructor and as such, they have access to the constructor scope. That's their privilege.
B) They aren't shared by its prototype.
A means that the function will be instantiated every time the constructor is being called. When you use the prototype, it's just linked.
B means that they are essentially different functions.
obj1.privileged !== obj2.privileged
Is there a specific reason behind this or was this an error in the spec or am I missing something?
No error from where I see it. It's just a language feature.
In what situation would you use a public method over a privileged method?
When you don't need access to any closures inside the constructor and want to take leverage of the prototype chain.
Not sure about the semantics and naming convention, but as far as patterns, here's how I'd break this down for the most cases:
privateFunc:
I'd use this type of function whenever I want to encapsulate some functionality inside a function (either when reusing this function several times, or simply because it has a logical reason to do so) that I don't want to expose as an API, usually because it doesn't make sense as an API.
publicFunc:
I'd use this type of function whenever I want to expose an API, and the implementation doesn't require any "closed" (as in closure) variables. Basically anything that uses the state of an instance of the type but needs no other resources. Also for "static" methods that are used directly from the type (same as Object.keys() for example), but this won't be declared on the prototype but rather directly on the type.
priviledgedFunc:
Same use case as publicFunc except the use of helper, "closed" variables is either required or greatly simplify implementation. There's a downside to this technique in that these methods are properties of each instance, and incur runtime penalty to construct and assign.
Why is there a distinction between privileged and public methods?
It's a consequence, not a driver, of the language's design. You will actually do fine without bothering yourself with this terminology distinction I think.
Why should I even bother with public methods, aren't privileged
methods more natural? They feel more intuitive as they allow access to
private methods and variables like in java.
Is there a specific reason behind this or was this an error in the spec > or am I missing something?
In what situation would you use a public method over a privileged method?
There are a couple of situations where you would want to bother yourself with public methods that come to mind:
Privileged methods are defined everytime an object is created while public methods are defined once at parse time. So if you are writing something that creates a bucket load of object, e.g. particle system, you may want to use public method.
You can use public methods are pure function without instantiating an object.
Your are thinking about this the wrong way. You should be thinking about scope here and not access level (public/private/protected) Javascript is not a traditional object oriented programming language.
In your example, the "privateMethod" is simply scoped to the "Foo" function, and thus cannot be accessed outside the function. Your "privilegedFunction" is attached to "this" which in javascript is the context of the "Foo" function. You can access it from an "instance" of Foo as your example shows because of scoping, and it has nothing to do with access level.

Property definition is method definition when using knockout

According to the Google style guide, methods should be defined on the prototype of a constructor and properties should be defined in the constructor using the this keyword.
I do most of my front end development using Knockout, which handles observing properties by turning them into functions. That is, all of my properties are now methods, more or less. Is this a significant performance hit? Are there any Knockout workarounds using JavaScript getters and setters?
So first, yes there is a plugin for knockout that uses getters and setters, but it only works in newer browsers. You sacrifice compatability to IE8< (this is unavoidable, since those browsers do not support javascript getters/setters). The plugin can be found here.
To your main point: understanding the style guides intent is important. Because methods are usually reusable, putting them on the prototype saves duplicated code and memory allocation. This is why it is a recommendation to put them on the prototype. However, knockout observables are not reusable. They behave like properties: they store information specific to an instance. This difference is important. They may be functions, but they are treated like properties.
The Google style guide simply does not address this scenario. It is not a performance hit to place them on the instance, because you are comparing it to a scenario that will not work. Placing observable's on the prototype will break the model. It isn't a performance hit to do the only thing that works.
As a final note, the getters and setters plugin doesn't make the functions disappear, it just hides them behind the getter and setter. Performance will not improve, because the same work still has to be done.

Efficiency of Plain Functions vs. Immediate Functions?

Someone mentioned that immediate or self-executing functions have to store the whole stack. Is this true...If so what are the pros and cons of using something like the module pattern (which is based on an immediate function) vs. a plain function?
A function is inherently private, but you can return items that you want to be public, so it can handle privacy.
The main difference I see, is that you don't have global imports or the ability to make sure that the developer ( wait that's me ) uses new with the function ( or it is complicated ).
In general when trying to provide privacy and state when should one use the module pattern and when should one just use a plain function?
A second side question is does a function provide state when used with new?
Any function closure that persists because there are lasting references to variables or functions inside it occupies some amount of memory. In today's computers (even phones), this amount of memory is generally insignificant unless you're somehow repeating it thousands of times. So, using the language features to solve your design problems is generally more important than worrying about this amount of memory.
When you say "the whole stack", the calling stack for a top-level self-executing function is very small. There's really nothing else on the stack except for the one function that's being called.
A function is also an object. So, when it's used with new, it creates a new object that can have state (it's properties) if you assign values to those properties. That's one of the main ways that objects are created in javascript. You can either call a function and examine it's return value or you can use it with new and the function serves as the constructor for a new object. A given function is usually designed to be used in one way or the other, not both.
The module pattern is generally used to control which variables are public and when making them public to put them into a structured namespace that uses very few top-level global variables. It isn't really something you choose instead of self-executing functions because they don't really solve the same problem. You can read more about the module pattern here: http://www.yuiblog.com/blog/2007/06/12/module-pattern/
You can read about a number of the options here: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth and http://www.klauskomenda.com/code/javascript-programming-patterns/.
It is easier to discuss the pros/cons of a given technique in light of a specific problem that one is trying to solve or a specific design issue rather than a generic discussion of which is better when the things you've asked about are not really solving equivalent issues.
The best reference I know of for protected and private members (which can be hacked into javascript, but are not a core language feature) is this one: http://javascript.crockford.com/private.html. You are making tradeoffs when you use this method instead of the default prototype feature of the language, but you can achieve privacy if you really need it. But, you should know that javascript was not build with private or protected methods in mind so to get that level of privacy, you're using some conventions about how you write your code to get that.

backbone js difference between getters vs direct access of model attributes

what is the advantage/ reason for backbone-js to use the syntax
//using a Model instance called model
model.get('attribute')
and not
model.attribute
Im just starting to use backbone and I always ind myself trying to access the attributes directly
If you look at the source code, the get function just calls to this.attributes[name].
http://backbonejs.org/docs/backbone.html#section-31
The benefit, though, is at least two-fold:
1) a consistent API that reduces the amount of code you are writing
2) the ability to override the get method and provide more complex access control
For example, there are several plugins for backbone that override how models work in order to provide nested model capabilities. it's very easy for them to allow you to write a get method like this:
model.get("submodel.attr")
and have that parse out the attr of the submodel sub-model. Without the get method, it would be more difficult to make this consistent with the API.
The underlying benefit from this is encapsulation, though. Until JavaScript provides true get/set properties that let us write code for getters and setters, we'll be stuck with work-around methods like Backbone's get and set.
Well .. for starters, model.attribute is absolutely NOT correct. model.set() is required in order to get change events to fire. You're very likely to forget this if you get in the habit of using model.attributes[attribute] instead of model.get(attribute)

arguments.callee.caller.this?

I'm 99.9% positive that this isn't possible, but there may be some obscure ecmascript function I don't know of in JS1.9 or something.
Does anyone know of any way to get the this object of the calling function?
If what you're really trying to do here is control access to your member variables and thus your question is really: "How do I restrict access to member variables?", then maybe you would benefit from reading this article "Private Members in Javascript". It's possible, but since it isn't a built-in language feature, it requires a particular style of coding your classes and methods to make it work.
I'm not an expert on this, but I think it uses a closure of the constructor to control access. Methods declared inside the constructor will have access to instance variables declared in the constructor. Any caller from outside the constructor will not (whether those other callers are other methods, derived class methods or outside callers).

Categories