gaoxinge gaoxinge - 9 months ago 32
Javascript Question

Is there any mistake in new Function

I have read the Function. So I try to transform function declaration into function expression by new Function. But I am stuck in the code below:

function Foo(name, age) {
Foo.prototype.name = name;
Foo.prototype.age = age;
}
var foo = new Foo(1,2); // this is ok
console.log(Foo.prototype.hasOwnProperty('name'));
console.log(foo.hasOwnProperty('name'));


However there is an error after transformation:



var Foo = new Function(['name', 'age'], 'Foo.prototype.name=name;Foo.prototype.age=age;');
var foo = new Foo(1,2); // error: Foo is not defined
console.log(Foo.prototype.hasOwnProperty('name'));
console.log(foo.hasOwnProperty('name'));





Is there any mistake? Any answer is helpful. Thank you.

The code is right in my chrome browser. However it makes an error on platform:


  • nodejs: 6.10.0

  • win7 64bit


Answer Source

The error is because var Foo isn't defined where the Function can reach it, at least not while using Node.

When you create a function from a string using the new Function() constructor, the function only has access to the global scope, regardless of where it's created.

And, when within a Node module, var Foo and var foo aren't global variables. They're local variables that exists only within the current file/module, within a "module" scope.

var bar = 'bar';
console.log(bar);        // function
console.log(global.bar); // undefined

To allow the new Function() to access Foo, you'll have to define the latter as a global variable (or a property of the global object).

global.Foo = new Function(['name', 'age'], 'Foo.prototype.name=name;Foo.prototype.age=age;');
var foo = new Foo(1,2);
// ...

Though, you should be aware that modifying the global scope/object like this is generally frowned upon in Node, since this goes against its intent/design of using isolated modules.


However, to define the function from an expression, you don't need to use the Function constroctor. Rather, you just have to place the declaration where an Expression is expected, such as after an assignment operator.

var Foo = function (name, age) {
    Foo.prototype.name = name;
    Foo.prototype.age  = age;
};
var foo = new Foo(1,2); // this is ok
// ...