0

I know that converting a buffer to a json object is trivial with:

JSON.parse(buffer)

But what about converting a buffer that contains a javascript object with functions to a real javascript object ??

I have files that contact objects with functions and I need to read these files in and save them to another master object.

While the task of reading the files is not a problem, I cannot find any way of converting the buffer back into a real javascript object again.

This is a very simple example of a file 'test.js' that I am trying to load

{
    get:function(){return 'hello'},
    somevar: "xxx",
    put: function(){return 'world'} 
}

Reading this data in it is a buffer, I can't convert using JSON as this contains functions and I cannot read using utf8 encoding as it will become a string !

var funcs = {}
fs.readFile('test.js',function(err,buff){
  funcs['test'] = buff;
})

Is it possible to read a file and convert it into a real javascript object ?

Edit

OK, I have found a solution but it is using the dreaded eval(), however this is backend code and as far as I can tell there's no way for anything to be injected by a user from the frontend, I would prefer not to use it but unless there's anything that will work without modifying the format of the files, I will use it:

var funcs = {}
fs.readFile('test.js','utf8',function(err,buff){
  eval('var_='+buff); 
  funcs['test'] = _;
})

2 Answers 2

1

For what it's worth, you could use the Function constructor. It's slightly safer than eval because it doesn't access the local scope. But it can still access global variables.

var script = buffer.toString('utf8');    // assuming the file is in UTF-8
var returnObject = new Function('return ' + script);
var myObject = returnObject();
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks David, I tried your suggestion and although it did not error, the object was not successfully created and I was unable to call the functions or read the vars.
What was the value of script? What was the value of myObject? The only way I can think this could have happened is if script has a newline character before the {. Then 'return ' + script would consist of a return statement (meaning return undefined;) followed by a separate expression which is never reached when the function runs. If it does have newlines near the start, you could try 'return ' + script.replace(/^\s*/g, '') to remove leading whitespace.
David you were right, the newlines and spaces caused the conversion to fail, I used script.trim() to clean it up and it works !
Oops, I spoke too soon, I was right the first time. If you use my simple test.js in the original post and try and call get it should fail. I have reverted to eval() and it's working again.
What's gone wrong this time? Does get need access to variables in the scope? If that's the problem then you should be able to fix it by making those variables arguments to the function. For example: if get: function() { return x+y; }, then do var returnObject = new Function('x','y','return ' + script.trim()); var myObject = returnObject(x, y);.
|
0

Depending on the complexity of the code you're dealing with, this approach may or may not suit your needs:

You can create a temporary file, say "test-module.js", which includes the object from "test.js" but with a module export prependend, for example:

module.exports = {
    get: function() { return 'hello' },
    somevar: 'xxx',
    put: function() { return 'world' } 
}

Then, from your main file, you can retrieve the file content already available as a Javascript object:

var funcs = {}
var buff = require('./test-module');
funcs['test'] = [buff.get, buff.put];

Would this solution work for you?

1 Comment

Thanks for the suggestion but not really, I have thousands of files some have one or 2 lines some have hundreds of lines of code. This is an attempt to break up some very huge libraries into individual functions which can be maintained separately.

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.