DEV Community

moose
moose

Posted on

The function(){of 'JS strings'}

This post is going to go over dynamic function creation and it will take a general look at how JS looks at strings, and different ways they can be used.

These methodologies should be avoided as they tend to deliver unpredictable results that often off little reasoning as to why the evaluated the way they did. There are also concerns around accidental invocations. Unless you do the due diligence to take it to task I wouldn't incorporate it. But, we've all been in the spot where we just need to make it work even if its a quick and dirty way of doing the deed. (technical debt.. cough ough..)

I think this is a cool characteristic of the language and one I believe developers should be aware of, as it is an important facet in which the language itself operates.

Example: (take a moment to picture how this is going to run)

/*
JS Regex - Vanilla bby
*/
var b = "" + (f = () => {
    (a = () => {
        console.log("hello, in a")
        setTimeout(() => {
            console.log("in time out :(")
        }, 1);
    }).call(a())
    console.log("out of timeout, in f")
}).call(f()) + ""

var str = "";
console.log("comparison check b, before timeout call");
console.log(typeof b === "string");
console.log(typeof b);

var res = undefined;

setTimeout(() => {
console.log(" first comparison check b ");
console.log(typeof b === "string");
console.log(typeof b);

console.log("second comparison check b");
console.log(typeof b === "string");
console.log(typeof b);

res = str.split(str, b);
console.log("first comparison check res");
console.log(typeof res === "string");
console.log(typeof res);
}, 1);
console.log(res);
console.log("third comparison check b");
console.log(typeof b === "string");
console.log(typeof b);
Enter fullscreen mode Exit fullscreen mode

What we have is a function within a string, or a string concatenated with a function. When run we will check the type of the value, and of a value and do a strict comparison check as to what each variable is. This is going to be run through the v8 engine, which really shouldn’t matter (let me know if you have found different)

Lets take a look now at what my output from the this code looks like:
Alt Text

Did you expect that output? I did not. In fact for the most part I cannot explain the repetition either outside of the variable initializing itself for comparison checks.

But I want you to pay attention to the fact that though the system saw it was a string, told me it was in fact a string, and did so with a strict comparison check multiple times: the b variable was not a string as it carried out the routine embedded inside of it.

What does this say?
Well it says there is some sort of duality in the way JS views strings (I've often thought of it as one big regex engine). That JS saw it was a string, but still had the direction to carry out the embedded instructions instead of print out what the instruction would be. Cant strings in fact be functions? Yes, in face strings can indeed be evaluated at runtime as functions. The next few examples were pulled from answered questions as I believe there is some great discussions on the topic.

Example 2

[https://stackoverflow.com/questions/43726544/how-to-call-a-function-using-a-dynamic-name-in-js]

//variables
var ta = 3213;
var da = 44;
var s = [];

//Create string representation of function
s[1] = function test0(){ alert(" + da + ");}; //this["test"+0]
s[0] = function test1(){ alert(" + ta + ");}; //this["test"+1]

s.forEach((fun) => { this[fun.name] = fun;});

// calling the function
this["test"+1](); //calls test1
this["test"+0](); //calls test0
Enter fullscreen mode Exit fullscreen mode

This is using an invocation to access the the two functions. This is a dynamic invocation which is a way a good amount of libraries are built (sans the dynamic way to invoke the function.

Example 3

[https://stackoverflow.com/questions/7650071/is-there-a-way-to-create-a-function-from-a-string-with-javascript]

var name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'
Enter fullscreen mode Exit fullscreen mode

This is using the "eval()" function to evaluate the string as a function instead of printing it. instead of printing it. Outside of a whonky DB return value, there really isn't a whole lot to use this with.

Example 4

[https://stackoverflow.com/questions/20129236/creating-functions-dynamically-in-js]

var f = new Function('name', 'return alert("hello, " + name + "!");');
f('erick');
Enter fullscreen mode Exit fullscreen mode

This is constructing the body and contents of the function and using the built the function feature to store a body that evaluates as a function and storing it in variable f.
I personally think this is a cleaner and more approachable way to do this task as it mitigates the concerns around accidental invocation. In the example, the 'name' param is the value being passed in for the function when called and the second param contains the contents of the function itself.

String can be evaluated as functions in JS, a characteristic of the language that not many others share. While fun to toy with to see what spits out the console, I think it best not to incorporate it en masse, but to understand better how the HUGE ecosystem surrounding the language itself is used.

Top comments (0)