var a = 1; function b() { a = 10; return; function a() {} } b(); console.log(a);
控制台打出来是1,在b函数中不是有a=10吗,这样声明是一个全局变量吧,,为什么打印的是1,是不是在全局这个范围找到的a的声明就不会去函数里找a的声明啦??求解。。谢谢大家
闭关修行中......
在b()里面,函数a()被hoist到函数b()的顶部,因此a = 10实际上是改变了前面定义的函数a()。然后return回到global环境,这里的a没有被影响到。
代码等价于:
var a = 1; function b() { function a() {} // 定义a为一个函数,此时函数b()内部的a和外边的a已经不一样了。 a = 10; //修改刚刚定义的a,a现在是10。 return; } b(); console.log(a);
JavaScript 解释器中存在一种变量声明被提升(hoisting)的机制,也就是说变量 (函数)的声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是 会被提升至最前面。 例如以下代码段: alert(foo); // function foo() {} alert(bar); // undefined function foo() {} var bar = function bar_fn() {}; alert(foo); // function foo() {} alert(bar); // function bar_fn() {} 输出结果分别是function foo() {}、undefined、function foo() {}和function
bar_fn() {}。
可以看到 foo 的声明是写在 alert 之后,仍然可以被正确调用,因为 JavaScript 解释
器会将其提升到 alert 前面,而以函数表达式创建的函数 bar 则不享受此待遇。
那么bar 究竟有没有被提升呢,其实用 var 声明的变量都会被提升,只不过是被先赋值
为 undefined 罢了,所以第二个 alert 弹出了 undefined。
所以,JavaScript 引擎执行以上代码的顺序可能是这样的:
创建变量 foo 和 bar,并将它们都赋值为 undefined。
创建函数 foo 的函数体,并将其赋值给变量 foo。
执行前面的两个 alert。
创建函数 bar_fn,并将其赋值给 bar。
执行后面的两个 alert。
注:
严格地说,再 JavaScript 中创建函数的话,还有另外一种方法,称为“函数构造法”: var foo = Function('alert("hi!");'); var foo = new Function('alert("hi!");'); // 等同于上面一行 此方法以一个字符串作为参数形成函数体。但是用这种方法,执行效率方面会打折扣,
且似乎无法传递参数,所以少用为妙。
在b()里面,函数a()被hoist到函数b()的顶部,因此a = 10实际上是改变了前面定义的函数a()。然后return回到global环境,这里的a没有被影响到。
代码等价于:
JavaScript 解释器中存在一种变量声明被提升(hoisting)的机制,也就是说变量
(函数)的声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是
会被提升至最前面。
例如以下代码段:
alert(foo); // function foo() {}
alert(bar); // undefined
function foo() {}
var bar = function bar_fn() {};
alert(foo); // function foo() {}
alert(bar); // function bar_fn() {}
输出结果分别是function foo() {}、undefined、function foo() {}和function
bar_fn() {}。
可以看到 foo 的声明是写在 alert 之后,仍然可以被正确调用,因为 JavaScript 解释
器会将其提升到 alert 前面,而以函数表达式创建的函数 bar 则不享受此待遇。
那么bar 究竟有没有被提升呢,其实用 var 声明的变量都会被提升,只不过是被先赋值
为 undefined 罢了,所以第二个 alert 弹出了 undefined。
所以,JavaScript 引擎执行以上代码的顺序可能是这样的:
创建变量 foo 和 bar,并将它们都赋值为 undefined。
创建函数 foo 的函数体,并将其赋值给变量 foo。
执行前面的两个 alert。
创建函数 bar_fn,并将其赋值给 bar。
执行后面的两个 alert。
注:
严格地说,再 JavaScript 中创建函数的话,还有另外一种方法,称为“函数构造法”:
var foo = Function('alert("hi!");');
var foo = new Function('alert("hi!");'); // 等同于上面一行
此方法以一个字符串作为参数形成函数体。但是用这种方法,执行效率方面会打折扣,
且似乎无法传递参数,所以少用为妙。