# 知识点总结
# 箭头函数和普通函数区别
- 1、箭头函数没有this,它会从自己的作用域链的上层继承this(因此无法使用apply/call/bind来帮定this);
- 2、箭头函数不可以使用arguments对象,该对象在函数体内不存在,如果需要,可以使用rest参数提代。
- 3、箭头函数不可以使用 yield 命令,因此箭头函数不能用作generator函数;
- 4、箭头函数不可以使用new命令,因为:
- 没有自己的this,无法调用 call,apply。
- 没有prototype 属性,而 new命令在执行时候需要将构造函数的prototype赋值给新对象的prototype.
# var/let/const 区别
# 1、声明过程
- var:遇到有 var 的作用域,在任何语句执行前都已完成了声明和初始化,也就是变量提升并且拿到undefined的原因;
- function: 声明、初始化、赋值一开始就全部完成,所以函数的变量提升优先级跟高;
- let:解析器进入一个块级作用域,发现let关键,变量只是先完成声明,并没有初始化。此时如果在作用域提前访问,则会报错 xx is not defined, 这就是暂时性死区的由来。等到解析到 有let的那一句才会进去初始化的阶段。如果let的那一行是赋值操作,则初始化和赋值同时进行。
- const、class都是同let一样的道理。
对比于var,let、const 只是解耦了声明和初始化的过程,var是任何语句执行前都完成了 声明和初始化,let、const仅仅在任何语句执行前只完成了声明。
# 2、内存分配
- var:会直接在栈内存里预分配内存空间,然后等到实际语句执行的时候,再存储对应的变量,如果传的是引用类型,那么会在堆内存里开辟一个内存空间存储实际内容,栈内存会存储一个指向堆内存的指针;
- let:是不会再栈内存里预分配内存空间,而且在栈内存分配变量时,做一个检查,如果已经有相同变量名存在就会报错;
- const:也不会预分配内存空间,在栈内存分配变量时也会做同样的检查。不过const存储的变量时不可以修改的,对于基本类型来说,无法修改定义的值,对于引用类型来说无法修改栈内存里分配的指针,但是,你可以修改指针指向的对象里的属性。
# 3、变量提升
可以认为是,只有let存在变量提升;
也可以认为,let、const、var都存在变量提升
- let/const:只是创建过程(声明)提升,初始化过程并没有提升,所以存在暂时性死区;
- var:创建和初始化过程都提升了,所以在赋值前访问会等到undefined;
- function:创建、初始化和赋值都被提升了。
# 函数变量及作用域
隐式全局变量:变量没有声明,直接赋值,执行到时,浏览器才会偷偷把变量提升为隐式全局变量
全局作用域:在函数声明之外的作用域
# 预解析
- 所有的变量声明,都会提升到最顶部,但不会提升赋值
- 所有的函数声明,都会提升到最顶部,但不会提升函数的调用
- 如果同时有多个 var 声明的相同的变量,前面的 var 将被忽略
- 如果同时有多个同名的函数,后面的函数将会覆盖前面的函数
- 如果声明的变量和声明的函数同名,声明的函数将会覆盖声明的变量
# 词法分析3步骤
- 先分析函数形参(默认值为undefined),再分析形参赋值(没有形参的直接忽略此步骤)
分析函数体中所有的变量声明:
- 2.1 如果变量名与形参名相同时,直接忽略var;
- 2.2 如果变量名与形参名不同时,就相当于声明了一个变量,如var foo,值为undefined;
- 分析函数体中所有的函数声明,
- 3.1 如果函数名与变量名相同,函数将作为变量的值;
- 3.2 如果函数名与变量名不相同,相当于var 函数名 = function 函数名 () {};
# 函数执行过程分为2步
词法分析过程; 执行过程
function scopeA(b) {
console.log(b, '===a==='); // b () {}
function b() {
console.log(b); // b () {}
}
b();
b = 1;
console.log(b, '=====last====='); // 1
}
scopeA(6);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
function t3(greet) {
console.log(greet); // greet() { };
var greet = 'hello';
console.log(greet); // hello
function greet() {
};
console.log(greet); // hello
}
t3(null);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
function test(a, b) {
console.log(a); // a() {}
console.log(b); // 2
var b = 234;
console.log(b); // 234
a = 123;
console.log(a); // 123
function a() {
}
var a;
b = 456;
console.log(b); // 456
var b = function () {
}
console.log(a); // 123
console.log(b); // function () {}
}
test(1, 2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a = 100;
function demo(e) {
function e() {
}
arguments[0] = 2;
console.log(e); // 2
if (a) {
var b = 123;
}
a = 10;
var a;
console.log(b); // undefined
f = 123;
console.log(a); // 10
}
var a = 6;
demo(1);
console.log(a); // 100
console.log(f); // 123
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var a = function b() {
console.log(123);
}
a(); // 123
b(); // 报错
1
2
3
4
5
2
3
4
5
题 →