Searching for appropriate answer proved difficult because of the existence of many other problems related to my keywords, so I'll ask this here.
As we know, functions in javascript are objects and they have their own properties and methods (more properly, function istances, inherited from Function.prototype).
I was considering adding custom properties for one function (method), let's skip the "why?" part and go straight to the code:
var something = {
myMethod: function () {
if (something.myMethod.someProperty === undefined) {
something.myMethod.someProperty = "test";
}
console.log(something.myMethod);
}
}
When inspected with Firebug's DOM explorer, the property is defined as expected. However, as I don't consider myself a javascript expert, I have the following questions:
- Can this method be considered "proper" and standards compliant? It works in Firefox but there are many things working as expected in web browsers and aren't by any means standards.
- Is this kind of altering objects by adding new properties to them a good practice?
"necromancing" here, but I think every great question needs simple answers:
Yes and Yes*
By attaching the properties to the function you clean up the scope, improve readability and add logical cohesion. An added benefit is that you document the relationship between the function and the variables. I think that's a superior design, much better than adding variables on the scope
Created some fun examples here and here. HERE AND HERE
* I think it's worth noting that you probably won't see this very often. most developers probably don't realize it's possible. Some people are crazy about every drop of performance... "JavaScript engines optimize based on the 'shape' of an object'..." blah blah blah... ut I think you can follow the rule you have for Objects and you'll do fine.
Attaching properties to functions is a beautiful (arguably sluggish/hack-ish) way of overloading the
()
operator, which in turn is usually used to implement functors: Object types that have one really important job, and all its other functionality (if there is any) is just a bunch of helpers. You could also interpret these functors as, basically, a "stateful" function where the state is public (most inline functions for example, have private state, that is state from the local scope).This JSFiddle demonstrates how we can use a function with custom properties for a
translator
function with additional utilities:As you can see, this is perfect for a translator whose sole purpose is to translate. Of course there are many more examples of theses types of objects, but they are by far not as common as types with diversified functionality, such as the classic
User
,Animal
Car
etc. types. To those sort of types, you only want to add custom properties in very few cases. Usually, you want to define those as more complete classes, and have their public properties reachable throughthis
and it'sprototype
.I realize I'm years late to this, but thought I'd add this example--requirejs sets a property called "amd" on the define() function, which is quite handy as the UMD pattern uses it to detect that the define() function that's in scope is in fact an AMD define() function.
RequireJS source: http://requirejs.org/docs/release/2.1.9/comments/require.js
UMD pattern showing this usage: https://github.com/umdjs/umd/blob/master/amdWeb.js