秋招快到了,咱们在准备笔试或者面试题的时候,常常会遇到一些题,给一段js代码,回答运行后的结果是什么,下面我来整理一下。java
一、做用域问题面试
(1)全局做用域闭包
值为0函数
这个函数运行时,外面alert(x)拿到的是全局做用域中x的值,第一个声明的var x=0;的值是全局做用域中的值,第二个在f函数中声明的var x=2的值是局部做用域的值,由于用var从新声明了一个变量,两个指向的是不一样的做用域,所以alert(x)返回的是0spa
(2)局部做用域3d
若是咱们把var x=2;中的var去掉,变成下面这样子blog
值为2作用域
出现这种状况是由于,var x=0;声明的是全局做用域的值,f()函数也是全局做用域,而后f函数中的值。x会覆盖掉外部的值,所以就会致使获得的值是2it
再来看一个例子io
这个值为3,4,i is not defined
这个也是由于x,y有声明而且在全局做用域中,这时就能获得x,y的值,而i是在f函数中命名的,在外部的全局中就不能调用到。
若是将alert()语句放在f函数中,像下面这样
值为3,4,20
二、函数覆盖问题
值为1,1
这里f函数将x的值置为1,而后虽然两次调用f()函数,可是函数已经产生覆盖,第一个函数覆盖了第二个函数,所以两次调用都是1
若是将上面的匿名函数f注释掉,以下
值为2,2
这时,已经不发生函数覆盖,就一直是2,
若是将命名函数注释掉
值为1,1
像这样,也不发生函数覆盖,也是只调用f函数、
要解决函数覆盖的方法,就先写命名函数,再写匿名函数
值为2,1
这样的话,命名函数f()先调用,匿名函数f后调用
总结:之后写函数时,尽可能写成匿名函数形式,var f = function(){}
三、变量和函数提高问题
一、函数未定义
变量未定义,直接是undefined
二、函数已定义
这里声明了变量,js解释器“前瞻性”查找全部变量定义,把它们“提高”到函数顶部,就出现undefined,第一个未定义就出现undefined,第二个定义了就出现1223
三、内部变量重复定义
这里使用了闭包函数,第一个name变量提高,就会出现undefined,原本能够访问到全局做用域的name,可是内部已经从新声明了,name变量提高,就会出现undefined。这里典型的使用了函数声明提早,函数体内的块级做用域覆盖住了外部name的全局做用域,而后因为函数声明提高,至关于在函数体内,先var name;而后console.log("Original name was"+name);而后name = "Underhill";console.log("New name is" + name);最后的值是同样的。
所以,建议全部变量的定义,都放在头部,并使用var a=XX,b=xxx这样定义。
四、函数直接调用
这里函数直接调用就没什么好说的
五、函数定义提高
函数定义提高仅仅做用域函数定义,而不做用于函数表达式
这里函数definitionHoisted(),已经提高,而函数定义不做用于函数表达式,所以就抛出TypeError
六、命名函数表达式
在这里,函数名字是funcName()是函数的一部分,不会获得提高,而varName()也找不到这个方法
七、闭包函数与全局函数
var result = f1();就调用了f1()函数,这时result即为f2,函数,result是全局变量
result() 调用完以后的值为999,这时就是调用了f2函数,并将值输出
nAdd(),调用完以后,这时nAdd()函数为全局函数,也是闭包函数,值为1000,
result(),这个调用f2函数,就输出1000.
8.闭包中的命名提高。
这里输出的值是999,由于1000传入进去,a的值被覆盖了,a变量命名提高,输出就是999;
九、函数覆盖问题
在js函数中,是没有函数重载的,之前学java的时候,当函数名是相同的,主要传递的类型或者参数不一样就会出现重载,两个均可以用,可是在js中
主要出现两个同名的函数,就会出现函数覆盖,第二个add函数,覆盖第一个add函数,而后,因为函数声明提早,就会直接将函数覆盖。
那么什么是函数声明提早呢?
函数声明提早就是变量在变量声明以前就是已经可用,通常用在函数体内,在一个函数体内是块级做用域,通常函数,内部同名函数会覆盖外部同名函数,而后又因为函数声明提早,就能够有值。
That's all,Thank you!