2

Is there a way to call a function which will call a class constructor, giving it the arguments, especially the instance name, provided in the call ?

The most important thing is that I want to pass the name of the instance I want to be created.

In other words, is there a way to have this working :

function instantiationOfSomething(instanceName, param1, param2, param3) {               
    instanceName = new mySomethingClass({
        ...
    });         
}

//call #1
instantiationOfSomething("circle", 2, 8, 87);

//call #2
instantiationOfSomething("ellipse", 2, 85, 87);

I don't have any possibility to act on the constructor, e.g. instantiationOfSomething(...) is not a part of my code but is a part of an API.

Here is a real code example (Google Maps API v3):

makeMarker("markerName1", latlng1, "label1", "Title1");
makeMarker("markerName2", latlng2, "label2", "Title2");

function makeMarker (name, latlng, label, title) { 

    //here is the tricky part
    instanceName = new google.maps.Marker({
        position: latlng,
        map: map,
        label: label,
        draggable: true,
        title: title
    });
}
11
  • 1
    What is the scope you would like to set a new instance? Anyway, you'd need eval to create a variable name dynamically, I'd prefer using objects here. Commented Aug 28, 2015 at 19:14
  • Maybe consider the call and apply functions since they both allow you to specify the object as the first argument? Commented Aug 28, 2015 at 19:15
  • the scope I'd like to have is global, because I need to add listeners to the objects I created (I work with Google Maps API v3). I already tried eval but I'm missing something I think... Commented Aug 28, 2015 at 19:21
  • I think you could do this better by not to pass any name, rather make a call like window.ellipse = instantiationOfSomething(2, 85, 87); and in the called functionreturn new mySomethingClass({...}); Commented Aug 28, 2015 at 19:43
  • I don't have the possibility to act on the constructor, because I use Google Maps API v3. Commented Aug 28, 2015 at 19:45

2 Answers 2

1

Simple answer

function createVariable(name, value)
{
    window[name] = value;
}

// Usage:
createVariable("x", 5);
console.log(x === 5); // true

Explanation

There is a term context in JavaScript. When you access a variable variableName you are actually accessing a variableName property in the current context.

Default context in browsers is window object. So, actually, these statements in a default (outer) context are identical:

var variableName = "Hello World";

document.body.innerHTML += variableName + "<br/>";
document.body.innerHTML += this.variableName + "<br/>";
document.body.innerHTML += window.variableName + "<br/>";

In JavaScript, talking about object property accessing, you may use both dot notation or brackets notation:

var variableName = {
  propertyName: "Hello World"
};

document.body.innerHTML += variableName.propertyName + "<br/>";
document.body.innerHTML += variableName['propertyName'] + "<br/>";

However, the last one allows use of characters that can't be used with dot notation, like spaces. Also, it allows dynamic names.

Combining all above, you can easily instantiate a variable with a dynamic name by assigning a property of default window context:

function createVariable(name, value)
{
    window[name] = value;
}

createVariable('stackoverflow', 'Hello World');
document.body.innerHTML = stackoverflow;

For example, in case of marker, it can be done this way:

function makeMarker (name, latlng, label, title) {
    // not that tricky part anymore
    window[name] = new google.maps.Marker({
        position: latlng,
        map: map,
        label: label,
        draggable: true,
        title: title
    });
}
Sign up to request clarification or add additional context in comments.

Comments

0

Couldn't pass the name to the constructor. However, I was able to use only one function to call the constructor. For those who are interested, the solution is quite simple, even if it is not "beautiful". I just racked my brains too much, instead of taking the shortest path. Here is how I did :

markerName1 = makeMarker(latlng1, "label1", "Title1");
markerName2 = makeMarker(latlng2, "label2", "Title2");

function makeMarker (latlng, label, title) {

//the scope is local
var temp= new google.maps.Marker({
            position: latlng,
            map: map,
            label: label,
            draggable: true,
            title: title
        });
temp.dosomething();
temp.addListener('dblclick', function(event) {
    alert('Damn, you double-clicked me !');
})

//temp is returned 
return temp;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.