以下代码段定义了一个用作对象构造函数的函数Robot()
,该函数创建一个对象。
function Robot(robotName) {
this.name = robotName;
this.sayHi = function () { console.log("Hi my name is "+this.name); };
this.sayBye = function () { console.log("Bye!"); };
this.sayAnything = function (msg) { console.log(this.name+" says "+msg); };
}
第二种方法是
function Robot(robotName) {
this.name = robotName;
this.sayHi = new Function ("console.log('Hi my name is '+this.name); ");
this.sayBye = new Function ("console.log('Bye!'); ");
this.sayAnything = new Function("msg","console.log(this.name+' says '+msg);" );
}
我正在阅读的书说-
第二种方法的唯一缺点是它将大量使用 更多的内存,因为每次创建时都会创建新功能对象 Robot对象的新实例。
我何时会喜欢以下内容?
var wally = new Robot("Wally");
在两种方法中,壁式机器人都有 3个功能对象。
wally.sayHi(); //1
wally.sayAnything("I don't know what to say"); //2
wally.sayBye(); //3
然后2nd approach
使用更多的内存?
答案 0 :(得分:2)
解析代码后,它将转换为引擎能够执行的内部表示。现在,对于常规代码,该常规代码在加载代码时发生一次。如果您将字符串动态转换为代码(与Function
一样),则在调用Function()
时会发生这种情况,因此每次构造函数都会被调用。因此,使用第二种方法,引擎必须创建并保留代码的另一个内部表示形式,因此,如果创建10.000实例,则必须有10.000个代码表示形式。此外,这不仅会消耗内存,还会降低性能,因为优化是在每个函数的基础上进行的,并且代码的解析也需要时间,因此第二种方法的执行速度可能会慢得多(是的,引擎可以消除这些差异,但我想可能不会)。
还有其他一些缺点:
1)IDE中没有突出显示语法
2)不可读的代码
因此,永远不要使用第二个版本。并获得一本新书:
1)学习如何从字符串动态创建函数毫无意义,您将永远不必使用它。
2)它说第二个更糟糕,因为“每次创建Robot对象的新实例时都会创建新的功能对象”,这同时适用于第一个和第二个代码段(因此,这并不是真正的原因)
答案 1 :(得分:0)
更多关于javascript的工作原理。
您知道,在首次启动时,javascript会创建AST并优化代码。因此,在第一种情况下,函数将被“预编译”一次。其次,每次都会进行AST和“预编译”
答案 2 :(得分:-2)
大多数引擎将创建一个新的堆栈框架(更多的内存),因为它必须为每个new Function("")
调用调用解释器,并带有一个匿名的IIFE(较难调试)。这类似于使用eval()
。除了内存问题外,它还可以进行注入攻击,并且还可能根据严格模式导致范围问题。