0

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.

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

  • nodejs: 6.10.0
  • win7 64bit
Caleb
  • 5,084
  • 1
  • 46
  • 65
gaoxinge
  • 459
  • 2
  • 8
  • 21
  • You can log Foo and see if it is a function – CaptainHere Mar 12 '17 at 02:36
  • Why would you want to do that? – Pointy Mar 12 '17 at 02:36
  • None of what you wrote makes any sense... – Alexander O'Mara Mar 12 '17 at 02:36
  • You are missing a closing ")" on the first line. Or maybe you meant that. Wacky code. – LiverpoolOwen Mar 12 '17 at 02:38
  • @ILikeToMoveItMoveIt Yes, It is a function object. – gaoxinge Mar 12 '17 at 02:40
  • @Pointy I am just learning the Prototype Chain. – gaoxinge Mar 12 '17 at 02:41
  • @LiverpoolCoder which ')' exactly? You can write an answer to fix this. Thank you. – gaoxinge Mar 12 '17 at 02:43
  • The second code block works fine for me as shown, so I'm voting to close the question as off-topic because there isn't enough information to reproduce the problem. – nnnnnn Mar 12 '17 at 02:46
  • @nnnnnn I use nodejs version v6.10.0 to run code by win64 platform instead of console of browser. Is there any difference? – gaoxinge Mar 12 '17 at 02:49
  • I don't know much about Node. Please [edit] the question to provide that detail. I only tested in Chrome, but I guess that code works for you too in the browser? – nnnnnn Mar 12 '17 at 02:51
  • @nnnnnn Yes, browser is ok. Thank you for pointing out this. – gaoxinge Mar 12 '17 at 02:52
  • var Foo = new Function(['name', 'age'], 'Foo.prototype.name=name;Foo.prototype.age=age;'); console.log(Foo.prototype.hasOwnProperty('name')); var foo = new Foo(1,2); // error: Foo is not defined console.log(Foo.prototype.hasOwnProperty('name')); console.log(foo.hasOwnProperty('name')); This returns false true false :D – CaptainHere Mar 12 '17 at 02:59
  • 1
    One issue will be scope. The string of code for a `new Function()` is evaluated in the global scope rather than within the closure/module scope that Node.js creates for variables in each file. So, it could find `global.Foo`, but not `var Foo`. – Jonathan Lonowski Mar 12 '17 at 03:16
  • what the matter to change prototype in constructor ? – zb' Mar 12 '17 at 04:05

1 Answers1

1

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.


Though, to define the function from an expression, you don't need to use the Function constructor. You can instead 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
// ...
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199