js 给一段代码,给出运行后的最终结果的一些综合情况、

秋招快到了,我们在准备笔试或者面试题的时候,经常会遇到一些题,给一段js代码,回答运行后的结果是什么,下面我来整理一下。

1、作用域问题

(1)全局作用域

值为0

这个函数运行时,外面alert(x)拿到的是全局作用域中x的值,第一个声明的var x=0;的值是全局作用域中的值,第二个在f函数中声明的var x=2的值是局部作用域的值,因为用var重新声明了一个变量,两个指向的是不同的作用域,因此alert(x)返回的是0

(2)局部作用域

如果我们把var x=2;中的var去掉,变成下面这样子

值为2

出现这种情况是因为,var x=0;声明的是全局作用域的值,f()函数也是全局作用域,然后f函数中的值。x会覆盖掉外部的值,因此就会导致得到的值是2

再来看一个例子

这个值为3,4,i is not defined

这个也是因为x,y有声明并且在全局作用域中,这时就能得到x,y的值,而i是在f函数中命名的,在外部的全局中就不能调用到。

如果将alert()语句放在f函数中,像下面这样

值为3,4,20

2、函数覆盖问题

 值为1,1

这里f函数将x的值置为1,然后虽然两次调用f()函数,但是函数已经产生覆盖,第一个函数覆盖了第二个函数,因此两次调用都是1

如果将上面的匿名函数f注释掉,如下

值为2,2

这时,已经不发生函数覆盖,就一直是2,

如果将命名函数注释掉

值为1,1

像这样,也不发生函数覆盖,也是只调用f函数、

要解决函数覆盖的方法,就先写命名函数,再写匿名函数

值为2,1

这样的话,命名函数f()先调用,匿名函数f后调用

总结:以后写函数时,尽量写成匿名函数形式,var f = function(){}

3、变量和函数提升问题

1、函数未定义

变量未定义,直接是undefined

2、函数已定义

这里声明了变量,js解释器“前瞻性”查找所有变量定义,把它们“提升”到函数顶部,就出现undefined,第一个未定义就出现undefined,第二个定义了就出现1223

3、内部变量重复定义

这里使用了闭包函数,第一个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这样定义。

4、函数直接调用

这里函数直接调用就没什么好说的

5、函数定义提升

函数定义提升仅仅作用域函数定义,而不作用于函数表达式

这里函数definitionHoisted(),已经提升,而函数定义不作用于函数表达式,因此就抛出TypeError

6、命名函数表达式

在这里,函数名字是funcName()是函数的一部分,不会得到提升,而varName()也找不到这个方法

7、闭包函数与全局函数

var result = f1();就调用了f1()函数,这时result即为f2,函数,result是全局变量

result()  调用完之后的值为999,这时就是调用了f2函数,并将值输出

nAdd(),调用完之后,这时nAdd()函数为全局函数,也是闭包函数,值为1000,

result(),这个调用f2函数,就输出1000.

8.闭包中的命名提升。

 

这里输出的值是999,因为1000传入进去,a的值被覆盖了,a变量命名提升,输出就是999;

 9、函数覆盖问题

在js函数中,是没有函数重载的,以前学java的时候,当函数名是相同的,主要传递的类型或者参数不同就会出现重载,两个都可以用,但是在js中

主要出现两个同名的函数,就会出现函数覆盖,第二个add函数,覆盖第一个add函数,然后,由于函数声明提前,就会直接将函数覆盖。

 

那么什么是函数声明提前呢?

函数声明提前就是变量在变量声明之前就是已经可用,一般用在函数体内,在一个函数体内是块级作用域,一般函数,内部同名函数会覆盖外部同名函数,然后又由于函数声明提前,就可以有值。

That's all,Thank you!

 

posted @ 2016-08-29 16:14  janna~  阅读(1226)  评论(0编辑  收藏  举报