变量对象中的函数声明

时间:2013-08-16 17:03:01

标签: javascript

test(); //working

function test(){//do something}

这与(全局)变量对象有关吗?在执行过程开始之前,函数是否会推送到变量对象?

更新: 好吧,我真正的问题是“提升”是如何工作的。要理解你需要看看execution context of javascript,是的,它与变量对象(它是执行上下文的一部分)有关。

2 个答案:

答案 0 :(得分:2)

请参阅Scope Cheatsheet on MDN

function foo() { } hoists foo自动填入范围顶部

  

这与(全局)变量对象有关吗?在执行过程开始之前,函数是否会推送到变量对象?

不,它只是悬挂。


考虑这个例子:

foo();
// ReferenceError: foo is not defined

(function(){
  foo();
  function foo (){
    console.log("A");
  };
})();
// A

(function(){
  foo();
  function foo (){
    console.log("B");
  };
})();
// B

foo();
// ReferenceError: foo is not defined

吊装只是将变量名称“提升”到范围的顶部。


我的观点:

从不将函数编写为:

function foo() { ... }

我更喜欢明确,因为魔术行为很糟糕;我总是将函数写为

var foo = function() { ... }

如果我觉得这个功能需要一个名字,我会给它一个名字,但仍然用var定义

var foo = function foo() { ... }

@bfavaretto提出了一个有效的担忧:

  

关于你的意见...... var foo = function(){...}也将foo提升到顶部,但是未定义的值。所以那里也有隐含的东西

是的,它确实使用foo值提升undefined,但事情将全部按预期工作。

foo();
// TypeError: undefined is not a function
// This is good. We don't want the above function to run like that.
// This is a fatal error; the script won't even continue to run as-is.
// Comment out the above line to get it to run.

var foo = function foo() {
  console.log("foo");
};

var foo2 = function foo() {
  console.log("foo2");
};

// Even with the same function name, these two functions will
// output the correct values.
foo();  // foo
foo2(); // foo2

所有这些都说,在同一范围内拥有两个具有相同名称标识符的函数是愚蠢的。但是,即使你犯了错误并编写了这样的错误代码,如果你正在使用如上所述的函数表达式,代码仍然可以工作。如果您只是使用原始问题中的命名函数,那肯定不会。

答案 1 :(得分:-1)

我认为你在这里谈论提升。 我总是喜欢标记函数而不是函数表达式。

这是一个函数表达式:

//Declaration 1
var foo = function(){

// code goes here
}
  • 在这种情况下,func表达式是匿名的,但分配给var foo。 供参考

这是标记的功能:

//Declaration 2
function foo(){
 // same code here
 }
  • 没有什么理由去表达var。您 应该总是尝试为构造函数使用带标签的语句,所以你 可以通过其构造函数识别对象的“类型”。

  • 人们大多使用吊装吊装只是意味着 在定义之前调用某些东西

    非常简单的例子

    foo(); // alerts 'hello'
    function foo() {alert('hello');}
    V/s 
    foo(); // throws an error since foo is undefined
    var foo = function() {alert('hello');}
    

REFER:var functionName = function() {} vs function functionName() {}