00:00
大家好,我是上硅谷H5学科讲师,我叫闫志勇。在程序员节日到来之际,由我来给大家分享几道面试题,本次主要分享的内容叫变量提升。首先在我的web里面,我新去创建一个门店文件,叫命点JS,我们本节课主要讲的内容呢是变量提升,好,大家先来看一段简单的代码,我呢定义一个变量叫u name,然后呢,我再去写一个函数叫fun,该函数呢我们只做一个简单的输出。那么变量提升这个知识点在笔试的环节中经常容易被考到,那么可能他考题的那形式呢是这样的,他会在这个变量之前去输出这个变量,然后呢,在函数体之前它去调用该函数,接下来他会问你这两行代码执行的结果是什么?如果说我们知道了什么是变量提升,对于这一道题而言很轻松就能答上来,但如果说你不了解什么是变量提升的话,很容易出错,哎,可能有的同学说这会报错。
01:13
当然,有的同学也会说,这也会报错,其实它真正的答案呢,是。这个是n find,那么下边这个答案呢,是正常执行函数。也就是这个conslo里边的内容会被打印好,那我们来分析一下为什么会这样。那这个时候我们就要讲一个东西,就是变量提升,我们得知道GS引擎在代码正式执行之前会做一个执行,应该是。它呢会做一个预处理的工作,那么这个预处理的工作去干嘛呢?主要是用来收集变量,然后呢收集函数,这是他要做的一些工作,那么做这些跟呃工作的依据呢,是以及我们的function。
02:25
找到Y以后,哎,将Y后边的变量定义,但是不赋值,哎,那也就是意味着如同这样,我去Y的一个变量。但是后面没有内容,那么其实它此时对应的值应该是什么?是under find,而找函数的话,我是找这个function,那么找到function以后呢,会提前定义该函数。
03:03
也就是说,我们函数的函数体是什么时候定义的呢?是在我们GS引擎在做预处理工作的时候已经定义好了。好,注意,那以上这些操作,我说的是在代码正式执行之前就已经做好了,那当他的预处理工作做好了以后,他会接着正往下去正式的执行我们的代码。那这个时候大家来看一下。当我在这去输出这个u name这个变量的时候,哎,你说。现在能不能理解他为什么是安?哎,那是因为your name这个变量在预处理的时候已经定义好了,只不过是没有值而已,哎,到这儿我相信大家都能理解了,那这个时候,哎,可能下边还会有一个输出,他会问你这个值是什么?有的同学一想到这个是安,那下面这个是不是也是呢?哎,注意千万不要忘了在这一步的时候,它是不是有一个赋值的操作啊,也就是说此时的UR name对应的值是吧?应该就是这一个字符串,科比啊。
04:14
好,没有问题,那我们接着往下来看,在这个函数fun之前,我们去调用这个函数,为什么会正常执行这个函数呢?道理也是一样的,就是说他在预处理的时候,哎,他已经去收集这个函数,并且定义了该函数,而代码执行到这一行的时候,我们的函数体已经定义好了,所以呢,它会正常的执行该函数,这个时候大家要注意,我函数体的定义是在预处理的时候,而。当我代码执行完这一行的时候,你说他还会再定义一次吗?哎,答案是不会的,注意函数体的定义,在代码正常执行的时候是不会执行的,是不会执行的。好,OK,来,我们来看一下输出的结果。
05:09
因为呢,我现在在node的环境里面,所以我通过note去执行一下,哎,大家看第一个是UN find,而第二个是科比,那么第三个是不是正常输出呀,好,这个就是变量提升,注意有时候面试官在问的时候会问,这个叫预处理。哎,他俩是一个道理,一个道理,只不过是叫法不一样。好,刚刚呢,我们已经带大家去看了一下变量提升,那如果你只知道这一点知识的话,去做这些笔试题是没有任何问题的,但是如果说我们想真正的去了解GS引擎底层到底是怎么去实现这个变量提升的话,我们还需要了解一个东西。哎,那这个东西呢,叫执行上下文,那现在呢,我们在下边去写一下,可能有的同学听过这个概念,包括呢,还有个叫执行上下文对象,好,那我们先来看什么是执行上下文。
06:17
执行上下文英文。翻译叫contact,叫哎,Context,有的人习惯叫它什么叫ec,哎,就是两个单词英文首字母的缩写,那执行上下文比较好理解的是哎,我们就叫它执行的环境,或者说我们叫它代码执行的。环境。那这个是好理解的,那这个环境是什么时候产生的,我又什么时候会进入到这个环境呢?哎,我们可以叫他什么叫时机,叫就是代码在正式执行之前会进入到执行环境,那也就是说执行上下文是在代码马上要执行的时候才产生的,哎,这个时候大家要区别一个东西叫作用欲,我相信懂GS的同学对这个概念应该是不陌生的。
07:26
那么大家可以回想一下,作用欲是什么时候产生呢?哎,可能有的同学已经想到了,作用域是在代码定义的时候产生的,哎,而我们的执行上下文是在代码马上要执行的时候产生的,哎,这个大家要区分开,好,那么进入到我们的执行上下文。你说进入到我们的执行环境,他要干什么事情,也就是他要做的工作有哪些,第一个他会去,哎,创建一个毕业量对象,那么这个变量对象呢,它主要去收集变量函数。
08:09
即函数的参数。哎,那么收集变量以及函数及函数的参数这一步其实就是我们刚刚讲到的什么叫变量提升,好,我们接着往下看,创建完变量对象以后。这个时候他要去做一件事情,叫确认哎,This的指向,确认this的指向,那么race的指向的话,我们大概分为两种,哎,第一种那就是全局,全局的race指向谁?那毫无疑问是温,那么还有一种叫局部。那么这个局部呢,其实说的是什么呀?哎,说的就是函数,那么函数的意思指向的是调用其的对象,这个如果说在系数的话,又分为很多种,比如说函数字调用是不是相当于是window度点方法调用啊,或者说是对象点一个函数调用,那么该函数的race是不是这个对象,包括还有什么构造函数,那这个时候是不是要去new这个函数啊?哎,New这个函数的话,This就是它的实例对象。
09:32
这些内容呢,在这呢,我们就不详细的去说它了,好,我们接着往下来看,确认完this指向以后,哎,大家可能突然想到一个问题,就是说我这个变量对象它用不用去区分呢?哎,其实这个时候和大家说一下,我们创建这个变量对象,它呢也分两种,一种叫全局,那么全局的这个变量对象是谁呢?其实它最终是window,而还有一个叫局部的变量对象,局部的变量温度我们可以看得到,那局部的变量对象是谁呢?
10:14
啊,首先我们得明确一个道理,该局部变量对象是肯定存在的,但是我让你说,我估计你也说不出来,哎,这个时候给大家说一下这个局部的变量对象,它呢。不,没有实际的指向,就是说这个东西它是一个抽象的,但是确实干嘛存在,OK,那这个是局部的变量对象。好,来,我们接着往下来看,第二步做完以后,哎,他还会去干一件事情,叫创建作用列。那其实这个好理解,它如何去创建作用列呢?哎,那就是负极作用一列,加上哎当前的什么变量对象。
11:10
哎,大家可以连起来看,首先你得明确一个道理,我们一说到有负极的话,那也就是说我当前变量对象所处的那个环境肯定不是全局啊,既然不是全局,那是吧,肯定是在函数的。某一个执行环境里边,哎,在这个函数正式执行之前,你想一下它的外层是不是有可能嵌套着很多层的。作用越。这没有问题,好,那么在他执行之前,我外层这些作用域他们是不是有关联,很有可能形成了一条什么作用域列,而当前的函数。他要查找变量的时候,如果说在当前的作用域下。
12:00
找没有找到,那么他会怎么办呢?哎,此时它会沿着作用欲链,是不是向它外层的作用欲去查找,直到找到全局啊,那么既然它要沿着作用链去找,那么是不是应该和外层的作用力关联上?哎,如何关联呢?就是串联起来,将负极作用力在。连接上它当前的那个变量对象,而我们查找变量的时候,正好是在当前作用域里边的变量对象去找,没有的话再去负极的作用链去找,好这个就是执行上下文,哎,它的一些概念,哎它的一些概念,那么最后呢,给大家去说一个东西,算是一个扩展。OK,那其实我们可以认为我们说的执行上下文,哎,我们叫它ec,我们可以认为它是一个大的什么大的对象,在这个对象里边呢,它主要包含哪些内容呢?哎,首先有一个叫我们刚说的SC,这个大家应该能懂,叫作用链,它包含的是什么?是负极作用链加当前的变量对象,那么在这之前呢,我们刚说的他上来是不是应该先去创建了一个叫变量对象的东西啊?
13:28
这个对象里面包含哪些东西呢?变量函数,函数的行参。好,那除了这些呢,还有什么叫race race呢,又分为两种,一种呢是全局的window,或者是局部的话,就是调用其他对象。OK,那这个是执行上下文的东西。那其实大家说到那个执行上下文对象指的是谁呢?哎,是this。
14:04
是this,那只有你把这些它底层的一些东西理解了以后,哎,才能更好的去运用它。本节课的内容我们就分享到这儿,如果说大家想了解更详细的视频资料或者说代码的话,可以关注上硅谷的官网去获取。
我来说两句