红叶何时落水
主要记录一下var,let的区别,以及变量声明提升与函数声明提升
var 用于定义一个变量,并且限制了这个变量的作用域
(function fn() {
var a = 'fn_var';
b = 'window_var';
})()
console.log(a);//=>undefined
console.log(b);//=>window_var
没有var而直接定义的变量视为window的一个属性(作用域自动提升到最上层)
let用于定义一个块级变量,并且不会被视为window的属性(即使在最顶层声明)
for(let i = 0; i < 2; i++) {
console.log(i);//=>0 1
}
console.log(i);//=>i is not defined
花括号内可以调用i,但花括号外便访问不到i了。
简单来说,var作用于一个函数,let作用于一个花括号
变量声明提升
在C语言中,所有的变量一般都会定义在函数开始的部分,全局变量直接定义在函数外。这就保证了,当我们想要调用某一个变量时,它已经被分配了一个地址空间,我们可以立马对这个地址进行操作。这符合单线程的思想。但在JS中,对变量的定义进行了优化。
console.log(a);//=>a = undefined,但a是存在的
var a = 1;
console.log(a);//=>1
//等同于
var a = undefined;
console.log(a);//=>undefined
a = 1;
console.log(a);//=>1
所有变量的定义在程序逻辑进行前,都会提升到作用域的顶部;注意,赋值操作不会被提升。
与此同时let声明不会被提升
console.log(a);//=>Error undefined,a是不存在的
let a = 1;
console.log(a);//=>1
在者,在同一个作用域中,var可以多次声明同一个变量,let不可以。
let a = 1;
let a = 3;//=>Identifier 'a' has already been declared
var a = 1;
var a = 2;
console.log(a);//=>2
那let的意义何在?
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)//=>5 5 5 5 5
}
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)//=>0 1 2 3 4
}
异步操作会在主线程都执行完了之后才进行处理,这时i地址里储存的都是最后一个值
而let变量声明不会被提升,且作用域为块级的特点,让第二个循环可以多次分配i的地址,即循环5次,就定义了5次i,并且i的地址都不同。
简单提一下 setTimeout的原理
程序运行到 setTimeout的时候, setTimeout开始计时,然后程序继续向下运行。之后主程序所有的同步任务执行完毕。开始处理异步任务。而异步任务在计时完毕后,会将第一个参数的函数以队列的方式进入到主程序。主程序开始处理它。
关于setInterval它会多出一个判定,判断一下上次的任务有没有搞完,没搞完,就不添加新任务,以此来确保任务进入队列的间隔都是相同时间。注意是进入队列的间隔,而不是1号函数执行完,2号函数开始执行的间隔。想实现后一种效果可以用setTimeout重写一下。
再有setTimeout(()=> {}, 0);并不是真的0,会有一定延时,4ns?
clearInterval会取消计时任务。
回到正题,函数声明的提升
fn();//=>fn
function fn() {
console.log('fn');
}
没有任何问题,并且函数内部的内容也会被一同提升。
突发奇想
fn();//=>fn is not defined
(function fn() {
console.log('fn');
})()
为圣莫?因为这是一个表达式,不是一个函数。没有分配地址。那么其他地方自然访问了个寂寞。
而且他没有返回值
console.log(1+function fn() {
console.log('fn');
}())//=>1 + undefined = NaN
再有,函数提升的优先级在变量之前
fn();//=>undefined
var a = 1;
function fn() {
console.log(a);
}
//等同于
function fn() {
console.log(a);
}
var a = undefined;
fn();
a = 1;
另外函数名字与变量名字是相互冲突的,这得益于JS的弱语言类型。