Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么JavaScript中没有挂起回调函数?_Javascript_Hoisting - Fatal编程技术网

为什么JavaScript中没有挂起回调函数?

为什么JavaScript中没有挂起回调函数?,javascript,hoisting,Javascript,Hoisting,我理解JavaScript中变量和函数声明的概念,它们被放在封闭范围的顶部。但是如果我有一个命名的回调函数,它不会被提升。我不明白为什么会这样。我有下面链接中的代码来解释这个场景 例如: function enclosingScope () { var b; function inner (def) { def(); } var a = 2; } // After hoisting due to compilation, the above changes to

我理解JavaScript中变量和函数声明的概念,它们被放在封闭范围的顶部。但是如果我有一个命名的回调函数,它不会被提升。我不明白为什么会这样。我有下面链接中的代码来解释这个场景

例如:

function enclosingScope () {
  var b;

  function inner (def) {
    def();  
  }
  var a = 2;
}

// After hoisting due to compilation, the above changes to 
function enclosingScope () {
  // Function declarations are hoisted before variables
  function inner (def) {
    def(); 
  }

  var b, a;
  a = 2
}

// But if I have a named callback, will that be hoisted?
function enclosingScope () {
  function inner (def) {
    def();
  }

  var b, a;
  a = 2

  inner(function cb () {
    console.log('Test callback hoisting')
  })
}

所讨论的行为不限于命名回调。这是任何命名函数表达式的工作方式。考虑以下事项:

function foo() {
  (function baz() { });
  console.log(typeof baz);
}

> foo()
< undefined
函数foo(){
(函数baz(){});
控制台日志(baz类型);
}
>foo()
<未定义

baz
无法在其主体外部访问。因此,这是一个与提升不同的问题。

我发现给出的答案太短,因此这里有一个更规范的解释:

Javascript区分函数声明

function f() {}
和函数表达式

var f = function () {} // anynomous function or lambda
var g = function h() {} // named function expression
函数声明是语句,而函数表达式是…,你猜怎么着?耶,表情。请注意,命名函数表达式的名称(
h
在给定示例中)只能在函数体内部访问(在给定示例中为
g

每当您在括号中嵌套函数声明时,它都会自动转换为表达式。这意味着您的
函数cb(){…}
只是一个命名函数表达式。但您不会将其分配给变量,而是将其作为参数传递给
internal

当涉及到函数表达式的提升时,只提升指定变量的声明。函数声明的情况并非如此:

console.log(f); // function f
console.log(g); // exists, but undefined
console.log(h); // reference error

function f() {}
var g = function h() {}
因为在您的示例中,
cb
没有分配给变量,所以不可能存在提升

因此,这两条线在起重方面是等效的:

inner(function cb(){});
(function cb(){});
奖金:
const
/
let

但是,当您尝试调用使用
const
let
声明的函数表达式时,在其声明之前,会在词汇上引发引用错误:

console.log(g); // reference error
const g = function h() {}

g
也被提升。但是为了保护您免受意外的
未定义的
s。翻译抛出一个错误。我认为这是明智的。

Q:当你尝试它时发生了什么?问:为什么还要问,而不只是自己尝试?你已经得到了密码-你发现了什么???我已经编辑了这个问题。如果您正在讨论cb()函数,它是一个命名函数表达式,并且您正在将对它的引用传递给internal()函数,那么您现在可以查看并提供帮助。函数表达式不会被提升,名称cb只能从该函数内部使用-它不会在该包含范围内创建变量cb,因此没有要提升的内容,事实上,在您的代码中,您永远不会在其他任何地方实际引用cb。提升发生在上下文中的
。不一定在全局上下文中。函数语句被挂起。函数表达式未被提升。