Javascript Point Overload

Hi, there is a way to overload the .. (dot) and [] operator in javascript. those. if I say obj.Name or obj ['Name'], it should call the general method in the obj class, passing Name as an argument. Similar functionality is available in python using the property method. But here I want ".Name" to be passed as an argument to a generic method.

like this..

function Data(){ this.getValue(name){ return '...' } } data = new Data() name = data.Name name = data['Name'] //both should call data.getValue() 
+8
javascript
source share
4 answers

Answer in 2010 : (see 2013 update below)

No, you cannot redirect the search for property names to your own function.

However , with ECMAScript5 you can define properties using "getters" and "seters". This is a new feature that is not yet widely supported, but when it is, it will do something vaguely similar. This is described in several parts of the specification . Therefore, if you defined all your properties this way and then sent the actual request to your central getValue function, you would end up getting what you wanted. Someday. :-) Except that he does not call getValue for a property that does not exist.


Answer in 2013 :

This will change soon (and already has one for modern Firefox users): ECMAScript 6th edition will have a proxy. They are defined in the specification as well as on this page (but draft drafts take precedence).

Proxies allow you to create objects that are true proxies (facades) for other objects. Here is a simple example that turns any property values ​​that are strings for all caps upon retrieval:

 var original = {"foo": "bar"}; var proxy = new Proxy(original, { get: function(target, name, receiver) { var rv = target[name]; if (typeof rv === "string") { rv = rv.toUpperCase(); } return rv; } }); console.log("original.foo = " + original.foo); // "bar" console.log("proxy.foo = " + proxy.foo); // "BAR" 

Live Example | A source

Operations that you do not override have default behavior. In the above example, we all redefine get , but there is a whole list of operations that you can connect to.

In the argument list of the get handler function:

  • target is an object that is proxied ( original , in our case).
  • name is (of course) the name of the returned property.
  • receiver - either the proxy itself, or something that is inherited from it. In our case, receiver is === proxy , but if proxy used as a prototype, receiver could be a descendant, therefore, it was on the function signature (but at the end, so you can easily refuse it if, as in our example above, you are not actually using it).

This allows you to create an object with the required getter and setter function:

 var obj = new Proxy({}, { get: function(target, name) { if (!(name in target)) { console.log("Getting non-existant property '" + name + "'"); return undefined; } return target[name]; }, set: function(target, name, value) { if (!(name in target)) { console.log("Setting non-existant property '" + name + "', initial value: " + value); } target[name] = value; } }); console.log("[before] obj.foo = " + obj.foo); obj.foo = "bar"; console.log("[after] obj.foo = " + obj.foo); 

Live Example | Source (notice how I left the receiver functions since we are not using it. receiver is an optional fourth argument to arg on set .)

The conclusion above:

  Getting non-existant property 'foo'
 [before] obj.foo = undefined
 Setting non-existant property 'foo', initial value: bar
 [after] obj.foo = bar 

Pay attention to how we get the message "nonexistent" when we try to extract foo when it does not exist yet, and again when we create it, but not afterwards.

+12
source share

No, you cannot overload or replace it in JavaScript. I wish I had a more comprehensive / informative answer for you ... but it is simply not possible, I think there has never been a need to add this ability.

+1
source share

In recent versions of JS, there really is something like Python properties .

Also see the question Javascript Recipients and Setters for Dummies?

This may be enough for you, although Python is even more flexible and compact.

+1
source share

As others have stated, this is not possible because operator overloading is not possible in ECMAscript.

If you really need to do this, I would use some preprocessing to convert parts of the code (and only those that really should be similar to tools) into tool code.

This can be easily done using a small regex like this

 var a= "var a = bc['foo']" // get this via xhr or something var re = /(\[(.*)\])|(\.([\w\d]+)\b)/g; var b = a.replace(re, function(m){ return ".get('" + m.replace(/[[\].'\"]/g,"") + "')"; }); b; // "var a = b.get('c').get('foo')" eval(b); 
0
source share

Source: https://habr.com/ru/post/650576/


All Articles