Printing full blown JavaScript objects to the page

The problem

I want to be able to print JavaScript objects to the page, a la wp_localize_script, with a faithful representation of the original object not only when it comes to values, WordPress function does that wonderfully, but when it comes to functions too.
To be clear this

$data = array('callback' => 'function(arg){console.log("hello there");}');
wp_localize_script( $handle, 'myObject', $data );

will produce this

var myObject = {callback: "function(arg){console.log("hello there");}"};

where the function is quoted and will hence, require the dreaded JavaScript eval function to be used restarting the whole thing from the PHP version like

$data = array('callback' => 'console.log("hello there");');
wp_localize_script( $handle, 'myObject', $data );

and then

(eval(myObject.callback))();

my grunt based setup has the following to say about the use of eval [caption id=“attachment_939” align=“aligncenter” width=“557”]I get it: no eval. I get it: no eval.[/caption] and furthermore it forces the definition of variables outside of the function signature and the following bad code smell.

The result

Given the $data object above I want the following to be printed to the page

var myObject = {"callback": function(arg){console.log("hello there");}};

to be able to do something like

myObject.callback();

My solution

I’ve looked into the Zend framework solution to the problem for a guide but found the solution too convoluted to be applicable in my context and simply came up with an homebrew solution of mine: the JsObject class

<?php

namespace tad\utils;

class JsObject
{
    protected $in;
    protected $out;

    public function toObject($arr)
    {
        if (!is_array($arr)) {
            throw new \InvalidArgumentException("Argument must be an array", 1);

        }
        $out = json_encode($arr);
        // remove quotes around functions
        $out = preg_replace("/(\"\\s*)(function.*?})(\")/ui", "$2", $out);
        // remove quote escaping
        $out = preg_replace("/(\\\\+(\"|'))/ui", "\"", $out);
        return $out;
    }

    public static function on($arr)
    {
        $instance = new self();
        $instance->setIn($arr);
        return $instance;
    }

    public function getOut()
    {
        return $this->out;
    }

    public function setIn($value)
    {
        $this->out = $this->toObject($value);
        $this->in = $value;
        return $this;
    }

    public function printOut($objectName, $echo = true, $doNotWrap = false)
    {
        $prefix = '<script type="text/javascript">' . "\n\t" . '//<![CDATA[' . "\n\t\t";
        $var = sprintf('var %s = %s;', $objectName, $this->out);
        $postfix = "\n\t" . '//]]' . "\n" . '</script>';
        $out = '';
        if ($doNotWrap) {
            $out = $var;
        } else {
            $out = $prefix . $var . $postfix;
        }
        if (!$echo) {
            return $out;
        }
        echo $out;
    }

    public function localize($handle, $objectName)
    {
        global $wp_scripts;
        $out = $this->printOut($objectName, false, true);

        if (!$wp_scripts) {
            return;
        }
        $wp_scripts->add_data($handle, 'data', $out);
    }
}

which will allow me to write code like

$data = array('callback' => 'console.log("hello there");');

// $handle is the script the object is localized for
JsObject::on($data)->localize($handle, 'myObject');

and have the wanted result of

<script type="text/javascript">
    <![CDATA[
        var myObject = {"callback":function(arg){console.log("hello there");}};
    ]]>
</script>

printed in the head of the page. The localize method will interact with WordPress but any other method will work in any PHP environment. [caption id=“attachment_940” align=“aligncenter” width=“1024”]JsObject JsObject[/caption]