JavaScript全局与局部作用域疑问:修改变量后全局值未变?
问题解答
先看你写的代码:
a = 1; function b() { a = 10; console.log(a); // prints 10; return; function a() {} // is this the same as writing var a = () => {}; ? } b(); // returns undefined console.log(a); // returns 1
为什么全局a的值仍是1而非10?
核心原因是函数声明的变量提升。JS在执行函数b之前,会先扫描函数内部的声明,把所有函数声明提升到当前作用域的最顶部。也就是说,你写的function a() {}虽然在return后面,但会被提前到函数b的作用域开头,相当于函数b实际是这样执行的:
function b() { function a() {} // 被提升到作用域顶部,成为局部变量 a = 10; // 这里修改的是局部的a,不是全局的 console.log(a); // 打印局部a的值10 return; }
因为函数内部已经有了局部的a变量(由函数声明提升而来),所以你在函数里写的a = 10只会修改这个局部变量,和全局的a完全无关。全局的a自始至终都是1,自然最后打印出来还是1。
函数内部的function a() {}是否等同于var a = () => {};?
完全不等价,核心区别有这几点:
- 变量提升规则不同:
function a() {}是函数声明,会被完整提升(包括函数体);而var a = () => {}是变量赋值,只有var a会被提升,箭头函数的赋值部分留在原地。比如在函数里提前调用a(),函数声明可以正常执行,箭头函数会报错a is not a function。 this指向不同:普通函数的this是在调用时确定的,取决于调用方式;箭头函数没有自己的this,它的this继承自外层作用域的this。- 构造函数能力:普通函数可以用
new关键字作为构造函数创建实例;箭头函数不能被当作构造函数,用new调用会报错。 arguments对象:普通函数内部可以访问arguments对象(存储调用时的参数);箭头函数没有自己的arguments,如果要访问外层函数的参数,得用剩余参数...args。- 原型对象:普通函数有
prototype属性;箭头函数没有prototype,无法通过它实现原型继承。
内容的提问来源于stack exchange,提问作者LongChalk_Rotem_Meron
相关产品推荐
相关产品推荐

