Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: Can I use square brackets ([]) operator as a function?

Tags:

javascript

Is it possible for any arbitrary object to obtain a reference to an accessor function that would act exactly as [] operator?

Something like the following?:

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

So that if I had an object foo instead of doing foo['bar'] I could call foo.get('bar')

like image 240
Alex Vayda Avatar asked Dec 08 '13 17:12

Alex Vayda


People also ask

How do you use square brackets in JavaScript?

What do square brackets mean in JS? The [] operator converts the expression inside the square brackets to a string. For instance, if it is a numeric value, JavaScript converts it to a string and then uses that string as the property name, similar to the square bracket notation of objects to access their properties.

Why is square brackets used in JavaScript?

Square brackets are used to index (access) elements in arrays and also Strings. Specifically lost[i] will evaluate to the ith item in the array named lost.

Under what circumstances would you need to use bracket notation to access a value in an object?

We must use bracket notation whenever we are accessing an object's property using a variable or when the property's key is a number or includes a symbol or is two words with a space.


2 Answers

You can write a function:

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

Then you can bind that function to some particular object:

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

Now, why is that interesting? The only reason I can think of is that it gives you an object (the bound version of the function) that you can pass to other code, allowing that code to get property values but not update them. I suppose that's kind-of useful, though I can't say I've found myself wanting it.

You can add a "get" function to the Object prototype, but if you do so I'd do it in such a way as to make it non-enumerable. Otherwise, you may have weird behavior of for ... in loops:

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

Another interesting thing to contemplate if you're doing functional-style programming is the semantics of your "get" function. The sample I did above makes it possible to create a function to get a particular property of an object too, in addition to being a getter for any property:

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

Now all that the function "getSomeObjectName" will do is fetch the "name" property value.

It might also be interesting to consider higher-order functions. A really useful notion is that of a "pluck" function, to pull a particular attribute from an object. It's kind-of like "get" but I'd write it differently:

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

Now I can make a getter as before, pretty much the same way:

var getter = pluck.bind( someObject );

Alternatively, I can make a "plucker" for a particular property name that will get that property from any object:

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

Now I can call:

getName( someOtherObject )

and that's effectively like calling

pluck( "name", someOtherObject )

because I've "pre-loaded" the first parameter ("name") in the "getName" function. That becomes really useful with things like the .map() facility:

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 call to .bind:

function plucker( name ) {
  return pluck.bind(null, name);
}

allNames = myArray.map( plucker("name") );
like image 110
Pointy Avatar answered Oct 13 '22 03:10

Pointy


Yes, by prototyping

var foo = {bar : 3};

Object.prototype.getz = function(what) {
    return this[what];
}

var value = foo.getz('bar'); // outputs 3

FIDDLE

No idea why you would need it ?

like image 25
adeneo Avatar answered Oct 13 '22 03:10

adeneo