这里同时出现了函数声明提前,和变量的预解析,但是不管(var foo = 11;
放哪里,都返回function
这里表述有误
为什么SF中Markdown的~~删除线~~不能用...),是什么原因
function bar() {
return foo;
foo = 10;
function foo() {};
var foo = 11;
}
console.log(typeof bar());//function 为什么不是number
网上查的资料:
http://www.bootcss.com/article/variable-and-function-hoisting-in-javascript/
解析器将当前作用域内声明的所有变量和函数都会放到作用域的开始处
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheetfunction
:Three forms with different scope behavior:
(为什么有三种...)declared
: as a statement at the parent function top-level
behaves like a var binding that gets initialized to that function initialization**"hoists" to the very top of the parent function, above vars**
函数声明提前到当前作用域最顶端,在var
之上,但还是不懂:最顶端,那不会被后来的var给覆盖么statement
:as a statement in a child block
behaves like a var binding that gets initialized to that function
does not hoist to the top of the parent functionexpressed
: inside an expression bound in the expression only
然后现在,问题变成了:为什么var foo
无论放在function foo...
前面还是后面,都返回function
function bar() {
var foo;
function foo() {};
return foo;
}
console.log(typeof bar());
天蓬老师2017-04-10 14:31:58
答案如 @yofine 代码所写,var foo = 11
实际上是两句话var foo; foo = 11
,函数中只有声明(包括变量声明和函数声明)会被提前(hosited),所以foo = 11
还是原来的位置。两次赋值都在return 之后所以自然是Function
了,如果把foo = 10
放到return 前面就是Number
了。
如果存在函数声明和变量声明(注意:仅仅是声明,还没有被赋值),而且变量名跟函数名是相同的,那么,它们都会被提示到外部作用域的开头,但是,函数的优先级更高,所以变量的值会被函数覆盖掉。
// Both the variable and the function are named myName
var myName;
function myName () {
console.log ("Rich");
}
// The function declaration overrides the variable name
console.log(typeof myName); // function
但是,如果这个变量或者函数其中是赋值了的,那么另外一个将无法覆盖它:
// But in this example, the variable assignment overrides the function declaration
var myName = "Richard"; // This is the variable assignment (initialization) that overrides the function declaration.
function myName () {
console.log ("Rich");
}
console.log(typeof myName); // string
另外,~~做删除线的是Markdown的扩展语法,SF对扩展语法支持的不全,你可以直接使用HTML标签做删除线。
黄舟2017-04-10 14:31:58
由于js有声明提前,你的代码等同于下面。
function bar() {
var foo;
function foo() {};
return foo;
//以下不会被执行
foo = 10;
foo = 11;
}
console.log(typeof bar());
黄舟2017-04-10 14:31:58
function bar() {
var foo;
return foo;
function foo() {};
foo = 11;
}
function foo() {}
函数声明会在执行前被解析 存在于当前上下文的任意一个地方 typeof(foo)
已经为 Function
而 var foo = 11
只会提前声明出变量 foo
PHP中文网2017-04-10 14:31:58
在ECMAScript中,有一个叫做执行上下文(Execution Contexts)的概念,他在理论上规定了函数在执行时的执行顺序[具体则是由浏览器引擎来实现,不过chrome的v8引擎和firefox的 xxx-spider引擎在实现上会有一些细节的差异。],这里涉及到的2个执行顺序的规则如下:
使用function声明的函数会最先被编译,因此在相同作用域中,我们总能直接使用function声明的函数;
使用var声明的变量和函数表达式会被自动提升到作用域的顶部,这种现象叫做hoisting
。
于是这个问题就很好解释了。
想要深入了解执行上下文,可点击这里
你也可以继续阅读汤姆大叔的这系列文章,非常有价值.深入理解javascript系列