内置的函数对象方法如何比函数文字使用更多的内存?

时间:2019-05-25 20:38:18

标签: javascript

以下代码段定义了一个用作对象构造函数的函数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 使用更多的内存

3 个答案:

答案 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()。除了内存问题外,它还可以进行注入攻击,并且还可能根据严格模式导致范围问题。