js 调用的位置不同到得不同的结果,why?

1. 调用在最下面

function add() {
    console.info(a, b, c);// 1 2 9
}
var a = 1, b = 2, c = 9;
add();

2. 调用在最上面

add();
function add() {
    console.info(a, b, c);//undefined undefined undefined
}
var a = 1, b = 2, c = 9;

3. 调用在中间

function add() {
    console.info(a, b, c);//undefined undefined undefined
}
add();
var a = 1, b = 2, c = 9;

第一段代码按照Java的语法,应该是变量在申明在前面,后面的函数才能拿到值的,如果按照JavaScript变量提升的话,第一段代码拿到的也应该是undefined。

这边的执行结果不是很理解,词法作用域和变量提升的理不清!

阅读 3.2k
7 个回答

Hoisting

函数在js中是个很不一样的存在,函数分为定义与执行,定义的时候有一个作用域,执行的时候又在一个作用域,你这里的第一段函数,执行在全局环境里,函数里找不到对应的值,就会在全局里找啊,全局里有,自然不会是undefined

算了,给你分解一下吧,上边的代码执行是这样的:

var a, b, c; // hositing

function add() {
    console.info(a, b, c);//undefined undefined undefined
} // 至于函数的定义,这里的位置不重要,

add(); // 执行函数,能找到定义,但是没赋值,所以undefined

a = 1, b = 2, c = 9; // 在函数执行后边赋值,晚啦,?

这回总该明白了吧?

新手上路,请多包涵

重点还是在变量提升,var和function关键字都会让变量提升;第一个不用解释;
第二个和第三个相当于
function add() {

console.info(a, b, c);//undefined undefined undefined

}
var a, b, c;
add();
a = 1; b = 2; c = 9;

在js执行之前,编译器会先定义当前作用域中的变量,但并不会赋值。
而函数表达式会提升到作用域顶部定义并赋值。
你的第二段代码等效于:

var a, b, c;
var add = function(){
    console.info(a, b, c);
}
add();
a = 1;b = 2;c = 9;

这里的知识类似于函数声明和函数表达式
用函数声明的方式会使变量提升,如,function a(){}当前作用域中function声明的函数的执行顺序会优先
使用var声明的函数
这里2,3中的a,b,c都没有一开始赋值,当然是undefined

1.预解释阶段:var只读“=”左边,也就是只读var的变量名,
函数是整个读取。
2.运行阶段,var读取“=”右边的,函数遇到如fn()的时候执行。
--整段代码从上往下,先预解释一遍,再执行一遍,所以会出现调用位置不同结果不同的现象

这里用有变量提升和函数提升,
第一段代码实际是这样的,
var a ,b ,c;
function add(){

console.info(a,b,c);

}
a=1,b=2,c=9;
add(); //1,2,9

第二段:
var a ,b ,c;
function add(){

console.info(a,b,c);

}
add() //undefined,undefined,undefined
a=1,b=2,c=9

第三段
var a ,b ,c;
function add(){

console.info(a,b,c);

}
add()//undefined,undefined,undefined
a=1,b=2,c=9

我也是根据下面这个博客理解的,
http://www.cnblogs.com/kawask...

你只要明白一个道理就行了,代码是按照顺序执行的。
第一个add执行的时候 abc已经声明了。肯定会打印的啊。
第二个add执行的时候 并没有执行到abc声明啊,肯定会是undefined啊
第三个add同理啊。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题