Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript overloading dot

Tags:

javascript

Hi is there a way to overload the '.'(dot) and [] operator in javascript. ie if I say obj.Name or obj['Name'] it should call a common method in the obj class by passing Name as argument. The similar kind of functionality available in python using property method. But here I want the ".Name" to be passed as argument to the common method.

like this..

function Data(){
    this.getValue(name){
        return '...'
    }
}

data = new Data()
name = data.Name 
name = data['Name']
//both should call data.getValue()
like image 524
Adhi Avatar asked Dec 31 '10 09:12

Adhi


People also ask

Is the use of DOT in JavaScript?

Table of Contents. In JavaScript, one can access properties using the dot notation ( foo. bar ) or square-bracket notation ( foo["bar"] ). However, the dot notation is often preferred because it is easier to read, less verbose, and works better with aggressive JavaScript minimizers.

What is dot operator in JavaScript?

The dot (.) is simply an operator that sits between its operands, just like + and -. By convention, the variables stored in an object that we access via the dot operator are generically called properties. Properties that happen to be functions are called methods.

Does JavaScript allow operator overloading?

Unlike the other programming languages, JavaScript Does not support Function Overloading.

Does TypeScript support operator overloading?

TypeScript provides the concept of function overloading. You can have multiple functions with the same name but different parameter types and return type. However, the number of parameters should be the same.


3 Answers

On recent JS versions, there is indeed something similar to Python's properties.

Also see question Javascript getters and setters for dummies?

It may be enough for you, although Python is still way more flexible and compact.

like image 105
Marco Mariani Avatar answered Oct 27 '22 12:10

Marco Mariani


Answer in 2010: (see below for a 2013 update)

No, you can't redirect property name lookups to your own function.

However, as of ECMAScript5, you can define properties with "getters" and "setters". This is a new feature which isn't widely-supported yet, but when it is, it will do something vaguely similar. This is covered in a couple of parts of the spec. So if you defined all of your properties that way, and then sent the actual request to your central getValue function, you'd end up with largely what you wanted. Someday. :-) Except that it won't call getValue for a property that doesn't exist.


Answer in 2013:

This is going to change soon (and it already has for up-to-date Firefox users): ECMAScript 6th edition will have proxies. They're defined in the draft specification, and also on this page (but the spec drafts take precedence).

Proxies let you create objects that are true proxies (facades) for other objects. Here's a simple example that turns any property values that are strings to all caps on 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 | Source

Operations you don't override have their default behavior. In the above, all we override is get, but there's a whole list of operations you can hook into.

In the get handler function's arguments list:

  • target is the object being proxied (original, in our case).
  • name is (of course) the name of the property being retrieved.
  • receiver is either the proxy itself or something that inherits from it. In our case, receiver is === proxy, but if proxy were used as a prototype, receiver could be a descendant object, hence it being on the function signature (but at the end, so you can readily leave it off if, as with our example above, you don't actually use it).

This lets you create an object with the catch-all getter and setter feature you want:

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 (Note how I've left receiver off the functions, since we don't use it. receiver is an optional fourth arg on set.)

The output of the above is:

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

Note how we get the "non-existant" message when we try to retrieve foo when it doesn't yet exist, and again when we create it, but not subsequently.

like image 34
T.J. Crowder Avatar answered Oct 27 '22 13:10

T.J. Crowder


Nope, you can't overload or replace it in JavaScript. I wish I had a more comprehensive/informational answer for you...but it just isn't possible, I guess there was never a need seen to add the ability.

like image 43
Nick Craver Avatar answered Oct 27 '22 12:10

Nick Craver