JavaScript对象文字表示法与普通函数及其性能影响

JavaScript Object Literal notation vs plain functions and performance implications?

本文关键字:函数 性能 影响 文字 对象 表示 JavaScript      更新时间:2023-09-26

假设我有如下函数:

function foo() {
}
function bar() {
}

我可以把上面写为对象文字表示法:

var Baz = {
  foo: function() {
  },
 bar: function() {
 }
};

就我对后一种情况的理解,无论是否调用任何Baz函数,脚本加载时都会创建Baz的实例。在前一种情况下,函数对象仅在调用该函数时创建。我的这些假设正确吗?

如果我是正确的,那么前者将比后者在很少调用这些函数的应用程序中具有更高的性能(更少的内存)。但后者的优点是它提供了更大的模块化和更低的全局命名空间污染。

从你的专业经验来看,你对此有什么看法?速度有差别吗?

在前一种情况下,函数对象只在调用该函数时创建。

不,函数将被创建。

注意,你也可以这样做:

function foo() {
}
function bar() {
}
var Baz = {
  foo: foo,
  bar: bar
};

或:

var Baz = (function() {
    function foo() {
    }
    function bar() {
    }
    return {
      foo: foo,
      bar: bar
    };
})();

Baz上的函数作为属性的主要目的是使它们在Baz上作为"方法"可用。这可能是为了方便,为了"命名空间"等等。在您的第一种形式(以及我上面的第一种形式)中,如果该代码处于全局作用域中,则foobar被添加到全局作用域中,这可能会很快变得非常拥挤(特别是在浏览器上)。在第二个例子中,唯一的全局符号是Baz,因为函数是匿名的。在我上面的最后一个例子中,唯一的全局符号是Baz,但是函数不是匿名的,它们有调试器和堆栈跟踪可以显示的名称(这是一件好事;更多。

当执行进入一个给定的上下文(全局上下文,或者与调用函数相关的上下文)时,这些事情就完成了:
  1. 创建一个幕后执行上下文对象。
  2. 为执行上下文创建一个幕后变量对象
  3. 在函数上下文中:
    1. arguments的变量对象添加了一个属性(可以用来访问参数的类似数组的东西)
    2. 为每个函数的命名参数添加一个属性到变量对象中,参数值为
    3. 如果函数有名称,则它的名称作为变量对象的属性添加,并具有函数对象的值。
  4. 属性是为在执行上下文中用var声明的每个变量在变量对象上创建的;它们的初始值是undefined(不管var是否有初始化器)。
  5. 上下文中的每个函数声明都会被处理。(函数表达式还没有处理;下面是更多不同之处。)在每个函数名的变量对象上创建一个属性,并接收函数对象作为其值。
  6. 开始逐步执行代码。
    • 像所有表达式一样,函数表达式在逐步流程中遇到时被求值。
    • var语句具有初始化式(例如,var a = 2;),被完全视为赋值语句(a = 2;);var方面的工作要早得多。(var经常被误解。例如,我们昨天就有这个问题。
你会注意到上面function 声明和function 表达式的区别。你可以通过查看你是否将结果用作右值 —也就是说,您是将结果赋值给变量,将其用作对象字面量中属性定义的右侧,还是将其传递给函数。如果是,它就是一个函数表达式。如果不是,它就是一个函数声明

函数声明示例:

function foo() {
}

函数表达式示例:

var foo = function() {
};

:

var Baz = {
    foo: function() { }
};

(foo行是对象字面值中的属性声明,使用函数表达式表示值)

Named函数表达式示例:

var f = function foo() {  // <== Don't do this (more below)
};

命名函数表达式应该是有效的,但它们在野外(特别是IE)的实现中支持很差,所以现在必须避免使用它们。这里更多。