程序是怎么执行的
传统编译过程
- 先进行分词
- 构建AST(抽象语法树)
- 代码生成
JS的执行过程
-
代码编译阶段
-
前置阶段
- 进行变量声明
- 变量声明进行提升,但是值为undefined;
- 非表达式的函数声明进行提升;
-
-
代码执行阶段
对于JS来说,一个变量,是如何被赋值和使用的,有什么区别?
`var a = 2`
-
`var a`-
编译器会先问作用域,是不是已经有一个a,在当前的作用域中?
- 是: 编译器会忽略这个声明,然后next
- 不是:在当前作用域中,生成一个新的变量,并命名为a;
-
-
`a = 2`-
编译器会问作用域,是不是已经有了一个a,在当前作用域中?
- 是:赋值为2
- 不是: 去上一层作用域中去找
-
作用域
作用域,就是根据名称查找变量的规则
词法作用域
词法作用域就是定义在词法阶段的作用域。
词法作用域就是你写代码的时候,奖变量写在哪里决定的,因此,当词法分析器处理代码时,会保持作用域不变。(除了eval,with)
函数作用域
函数作用域就是,属于这个函数的全部变量,都可以在整个函数内使用。
上下文
词法作用域,是在写代码的时候,或者在定义时,确定的;
而动态作用域,是在运行时确定的
[高阶函数]
题目一:打印下面会出现什么情况?
答案: undefined 10 [Function:foo] 1
闭包
面试时都会被问到什么是闭包?如何解释?
函数嵌套函数时,内层函数引用了外层函数作用域下的变量,并且内层函数在全局环境下课访问,就形成了闭包
执行上下文 不等于 词法作用域
题目一:
经典闭包
答案: 1 2 3 4
题目二:
答案:10
题目三:
答案: 2 不是undefined,因为bar调用的还是innerFoo函数,而innerFoo函数是一个闭包,引用了a值,如同下面一样
函数可以作为变量,返回值,参数
函数时一等公民
闭包的使用场景?
- 当我使用FP的时候,基本上就有闭包了
- 当一个函数执行,和上下文相关的时候,基本就有闭包了
- 闭包就是用来保存执行环境的
this
this 指向什么?
this 的指向,是根据上下文,动态决定的。
- 在简单调用时,this 默认指向的是 window / global / undefined(浏览器/node/严格模式)
- 对象调用时,绑定在对象上;
- 使用 call . apply . bind 时,绑定在指定的参数上;
- 使用 new 关键字是,绑定到新创建的对象上; (以上三条优先级:new > apply/call/bind >对象调用)
- 使用箭头函数,根据外层的规则决定。
题目一:
答案: window undefined
题目二:
答案: yunyin
题目三:
答案:o1 o1 undefined 第三个没有函数调用它,它相当于在window默认调用o1.fn
题目四 :
答案: 10 ,9 ,3 ,27 ,20