JavaScript: Can square brackets ([]) be used as a function?

Is it possible for any arbitrary object to get a link to an access function that will act as the operator [] ?

Something like the following ?:

 function get(x) { return this[x] } 

So, if I had a foo object instead of executing foo['bar'] , I could call foo.get('bar')

+7
javascript
source share
4 answers

You can write a function:

 function get( propertyName ) { return this[ propertyName ]; } 

Then you can bind this function to a specific object:

 var myObject = { /* ... */ }; // that looks like a little face, kind-of var getter = get.bind(myObject); 

Now why is this interesting? The only reason I can think of is that it gives you an object (a related version of the function) that you can pass to another code, allowing this code to get property values ​​but not update them. I believe this is useful, although I cannot say that I myself wanted this.

You can add the get function to the prototype of the object, but if you do this, I will do it in such a way as to make it unenumerable. Otherwise, weird behavior of for ... in loops may occur:

 Object.defineProperty(Object.prototype, "get", { value: function( key ) { return this[key]; } }); 

Another interesting thought, if you are involved in functional style programming, is the semantics of your get function. The sample I made above allows you to create a function to get a specific property of an object, except that it is a getter for any property:

 var getSomeObjectName = get.bind( someObject, "name" ); 

Now all that getSomeObjectName will do is get the value of the name property.

It may also be interesting to consider higher order functions. A really useful concept is the pluck function to pull a specific attribute from an object. It’s kind of like β€œget”, but I would write it differently:

 function pluck(propertyName, object) { object = object || this; return object[propertyName]; } 

Now I can do getter, as before, in much the same way:

 var getter = pluck.bind( someObject ); 

Alternatively, I can make plucker for a specific property name that will receive this property from any object:

 var getName = pluck.bind(null, "name"); 

Now I can call:

 getName( someOtherObject ) 

and it's effective as a challenge

 pluck( "name", someOtherObject ) 

because I "preloaded" the first parameter ("name") in the "getName" function. This becomes really useful in things like the .map() object:

 var myArray = [ { name: "Thomas", type: "tank engine" } , { name: "Flipper", type: "dolphin" } , { name: "Rocinante", type: "horse" } // ... ]; var allNames = myArray.map(pluck.bind(null, "name")); 

You can, of course, write a wrapper function to hide the somewhat ugly .bind call:

 function plucker( name ) { return pluck.bind(null, name); } allNames = myArray.map( plucker("name") ); 
+3
source share

Yes, prototyping

 var foo = {bar : 3}; Object.prototype.getz = function(what) { return this[what]; } var value = foo.getz('bar'); // outputs 3 

Fiddle

I don’t know why you need it?

+3
source share

You can.

http://jsfiddle.net/sdaDK/

 var foo = { bar: 'foo2', get: function (a) { return this[a]; } } alert(foo.get('bar')); 
0
source share

If you need this function for only one object, you can do

 var myObject = { x: 'anything', get: function (x) { return this[x]; } } alert(myObject.get('x')); 

Or, if you need this for the whole object, you need to extend the prototype of the Object class

 var myObject = { x: 'anything' } Object.prototype.get = function(x) { return this[x]; } var value = myObject.get('x'); 

There is a way in javascript prototype to extend any property.

0
source share

All Articles