目录
一、作用域&变量提升&闭包问题
1.代码输出结果
(function(){
var x = y = 1;
})();
var z;
console.log(y); // 1
console.log(z); // undefined
console.log(x); // Uncaught ReferenceError: x is not defined
改变我自己的一个固有印象:var定义的对象不管在哪儿都是全局对象,var如果在全局作用域下定义的对象才是window上的对象,这叫var可以添加全局属性,而let和const就算在全局作用域下定义对象也不能定义在window身上。
而var没有块级作用域是它的作用域是全局作用域或者函数作用域,而不是块级作用域(if、for等语句不能限制var的作用范围。
然后再来看这道题,IIFE函数执行,var x=y=1;实际上会从右向左执行,y=1 => y没有使用var声明,所以它就会是一个全局变量,然后var x=y,在函数内声明所以是局部变量,x在外侧输出会报错。
2.代码输出结果
var a, b
(function () {
console.log(a);
console.log(b);
var a = (b = 3);
console.log(a);
console.log(b);
})()
console.log(a);
console.log(b);
IIFE执行,a、b是全局变量,一开始只声明没有定义(初始化),前两次输出undefined
然后和1一样,3,3,undefined,3(不是报错了,有声明)
3.代码输出结果
var friendName = 'World';
(function() {
if (typeof friendName === 'undefined') {
var friendName = 'Jack';
console.log('Goodbye ' + friendName);
} else {
console.log('Hello ' + friendName);
}
})();
Coodbye Jack
因为函数和var都会被变量提升,如下:
var friendName = 'World';
(function() {
var friendName
if (typeof friendName === 'undefined') {
friendName = 'Jack';
console.log('Goodbye ' + friendName);
} else {
console.log('Hello ' + friendName);
}
})();
4.代码输出结果
function fn1(){
console.log('fn1')
}
var fn2
fn1()
fn2()
fn2 = function() {
console.log('fn2')
}
fn2()
提升完之后的代码:
然后输出fn1 fn2 fn2,错!!!!
因为fn2 = function(){}这是一个函数表达式,而不是函数声明(function(){}),只有函数声明才有变量提升,函数表达式只是一个赋值操作,不会有变量提升
所以输出是fn1 报错 fn2
5.代码输出结果
function a() {
var temp = 10;
function b() {
console.log(temp); // 10
}
b();
}
a();
function a() {
var temp = 10;
b();
}
function b() {
console.log(temp); // 报错 Uncaught ReferenceError: temp is not defined
}
a();
6.代码输出结果
var a=3;
function c(){
alert(a);
}
(function(){
var a=4;
c();
})();
js中变量的作用域只会在定义的时候就确定好,跟后来谁调用没关系。
所以输出为3
总结:
首先是var和函数声明会有变量提升,当然了,var的变量只有声明提升,定义不会。
没有用var/let/const声明的变量默认是全局变量,var有函数作用域,用它声明的在函数作用域内不是全局变量。
js变量的作用域在定义的时候就确定好了,跟this不一样。