0

I have string logo.cr.Button and function

logo.cr.Button = function(){
 //something
}

var strg = 'logo.cr.Button';
strg();

now somehow i have to make that string a function call

like strg(); but it is saying

strg is not a constructor

here

6
  • edited my question a bit please check again Commented Feb 11, 2017 at 16:40
  • not working @thomas says not a function Commented Feb 11, 2017 at 16:46
  • 1
    Sounds like an XY Problem. Why are you needing to do this in the first place? Provide more details about higher level problem you are trying to solve Commented Feb 11, 2017 at 16:47
  • @Waqar: I forgot about the name-spacing issues, my bad. Commented Feb 11, 2017 at 16:52
  • yeah thats that someone recomend @thomas ty Commented Feb 11, 2017 at 16:53

4 Answers 4

1

Generally when we write JavaScript functions the resulting function declaration looks like this:

function demo() {
  // function stuff here
}

You’re probably more than aware that “In JavaScript Functions are first-class Objects”. It’s a phrase that is spouted everywhere, and for good reason. It’s a very powerful idea that has worked to elevate JavaScript to where it is. We’re not going into the details of first-class objects here. All we care about is the fact that, in JavaScript, functions are objects. This means that the above function can also be declared by calling its Constructor:

var demo = new Function();

Now lets imagine we have a function with parameters and instructions:

function demo(name, age) {
  console.log('my name is ' + name);
  console.log('my age is ' + age);
}

and now to convert it to Constructor syntax:

var demo = new Function(
  "name,age",
  "console.log('my name is ' + name);" + 
  "console.log('my age is ' + age);"
);

This makes it pretty easy to see that these two functions are the same, they are just declared differently. The important difference is that one has easily accessible strings that we should be able to manipulate.

This applies to your function in a very similar way.

var strfunc = new Function ("", "logo.cr.Button()");

I can't seem to format this because I'm on mobile. But i will asap.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks that was very helpful
You should not use eval or new Function in such a way. In general it is a bad idea if new Function will access variables that are outside of the scope of this function, because it will result in unexpected behavior if you e.g. need to use a transpilar or a minification script.
@t-niese I understand eval not being used, but new Function I've used with a transpiler and with a min script with no issues whatsoever. If you're worried about scope you could simply bind the appropriate context into the Function or pass it in as a parameter. I don't really see any grounds for the statement "you should not". I'd be happy if you could point out in more detail why you think that?
eval and new Function have the same problems. Both convert a string to code at runtime. As of that every transpiler, minification or linting script will normally ignore those strings when processing the code. If logo. is renamed by the transpiler or the minification script, then the code given as string would not be changed and will fail. So if you use eval or new Function then you should always make sure that you do not access variables that are defined outside of the evaluated code. Except if it is guaranteed to exist even after minification or transpile.
I can see the concern. I suppose maybe I'm just a bit more lenient in my coding. I wouldn't argue that new Function should not be used more often than very, very rarely, but in terms of generating a function from a string, if you HAVE to, I find it to be the most appropriate and sensible solution. I will say that I honestly did not have any issues with a babel/js lint/min setup but perhaps I was just very lucky. That being said, I still disagree in that "you should not". If you can't find another way than this will work and there are situations where it, I think, is appropriate.
|
1

Use eval("logo.cr.Button")();

This will execute the function, of course if you have an object like:

var logo = {
    cr: {

    }
};

Comments

1

This won't work because JavaScript thinks you are using dot notation. When you write logo.cr.Button() JavaScript is looking for a function Button() within the object cr which is in the object logo.

I recommend changing the name to logoCrButton = function()...

Comments

1

You could use eval, but its not recommended. Secury issues are just one reason, because an user might exploit eval to execute different code that is not supposed to be executed. Within this question it is explained fully.

var logo={cr:{}};
logo.cr.Button = function(){
  console.log("something");
}

var string = "logo.cr.Button()";
eval(string);

If you can avoid eval then use a normal function call, an object or an array instead. For insteads Iterating through an array is much better and more stable compared to evaluating some parameters dynamically, as you can see here.

This second example does not use eval, but nevertheless you can call a certain function by using a string:

var obj={logo:{cr:{Button:function(){console.log("something");}}}};

var string = "logo.cr.Button";

function callFunctionByString(string,obj){
  var parts = string.split('.');
  parts.forEach(function(part){
    obj = obj[part];
  });
  obj();
}

callFunctionByString(string,obj);

Hope this helps.

2 Comments

If its not a good practice that why would i use this
Hope my second example is also appropriate to your question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.