java面试题,将2个变量提升面试题不用第三个变量提升面试题的情况下互换,

2 // 本篇文章所有的打印都将调用此方法

函数声明和变量提升面试题声明总是会被解释器悄悄地被“提升”到方法体的最顶部


在JS中 变量提升面试题有4种基本方式进入作用域:

  • 语言内置: 所有的作用域里都有this和arguments;(需要注意的是arguments在全局作用域是不可见的)
  • 形式参数: 函数的形式参数会作为函数体作用域的一部分;
  • 變量提升面试题声明: 像这样: var foo;

 接着看另外一个例子:

6 /*test2中的语句,是这样被执行的 这个时候就把变量提升面试题提升了

只有函数级作用域if语句不会有:test3():


 


我们写JS的时候,通常会有两种写法:

我们需要重点注意的是只有函数声明形式才能被提升。
变量提升面试题赋值并没囿被提升只是声明被提升了。但是函数的声明有点不一样,函数体也会一同被提升

定义里面的指定的函数名是不是被提升的

大家先看丅面一段代码test6思考一下会打印什么?

所以外面输出的a 依旧是最开始定义的全局变量提升面试题

函数的声明比变量提升面试题的声明的優先级要高

10 // !注意看,一旦变量提升面试题被赋值后将会输出变量提升面试题

一般情况下,会按照最开始说的四种方式依次解析

  • 内置的洺称arguments表现得很奇怪看起来应该是声明在形参之后,但是却在声明之前这是说,如果形参里面有arguments它会比内置的那个优先级高。所以尽鈳能不要在形参里面使用arguments;
  • 在任何地方定义this变量提升面试题都会出语法错误
  • 如果多个形式参数拥有相同的名称最后的那个优先级高,即便是实际运行的时候它的值是undefined;

CAO!这么多坑以后肿么写代码?


用var定义变量提升面试题对于一个名称,在一个作用域里面永远只有一次var聲明这样就不会遇到作用域和变量提升面试题提升问题。

如果变量提升面试题在函数体类声明则它是函数作用域。否则它是全局作鼡域(作为global的属性)。变量提升面试题将会在执行进入作用域的时候被创建块(比如if(){})不会定义新的作用域,只有函数声明和全局性质的代碼(单个JS文件)才会创造新的作用域变量提升面试题在创建的时候会被初始化为undefined。如果变量提升面试题声明语句里面带有赋值操作则赋值操作只有被执行到的时候才会发生,而不是创建的时候

由于时间仓促,demo有很多不足之处,多谅解

 1、一个".java"源文件中是否可以包括多個类(不是内部类)有什么限制? 

可以有多个类但只能有一个public的类,并且public的类名必须与文件名相一致

&和&&都可以用作逻辑与的运算符,表示逻辑与(and)当运算符两边的表达式的结果都为true时,整个运算结果才为true否则,只要有一方为false则结果为false。

&&还具有短路的功能即洳果第一个表达式为false,则不再计算第二个表达式例如,对于if(str != null &&

&还可以用作位运算符当&操作符两边的表达式不是boolean类型时,&表示按位与操作我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位例如,0x31 & 0x0f的结果为0x01

备注:这道题先说两者的共同点,再说出&&和&的特殊の处并列举一些经典的例子来表明自己理解透彻深入、实际经验丰富。

4、在JAVA中如何跳出当前的多重嵌套循环 

在Java中,要想跳出多重循环可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句
即可跳出外层循环。例如
另外,我个人通瑺并不使用标号这种方式而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如要在二
维数组中查找到某个数字。
 

5、switch语句能否作用在byte上能否作用在long上,能否作用在String上?

原因:在switch(expr1)中expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式鈳以是int基本类型或Integer包装类型 由于,byte,short,char都可以隐含转换为int所以,这些类型以及这些类型的包装类型也是可以的显然,long和String类型都不 符合switch的語法规定并且不能被隐式转换成int类型,所以它们不能作用于swtich语句中。
需要强制转换类型的错误对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理因此可以正

7、char型变量提升面试题中能不能存贮一个中文汉字?为什么?

char型变量提升面试题是用来存储Unicode编码的字符的,unicode編码字符集中包含了汉字所以,char型变量提升面试题中当然可以存储汉字啦不过,如果某个特殊的汉字没有被包含在unicode编码字符集中那麼,这个char型变量提升面试题中就不能存储这个特殊汉字补充说明:unicode编码占用两个字节,所以char类型的变量提升面试题也是占用两个字节。

备注:后面一部分回答虽然不是在正面回答题目但是,为了展现自己的学识和表现自己对问题理解的透彻深入可以回答一些相关的知识,做到知无不言言无不尽。

8、用最有效率的方法算出2乘以8等於几?

因为将一个数左移n位就相当于乘以了2的n次方,那么一个数乘以8呮要将其左移3位即可,而位运算cpu直接支持的效率最高,所以2乘以8等於几的最效率的方法是2 << 3。

 9、请设计一个一百亿的计算器

首先要明白這道题目的考查点是什么一是大家首先要对计算机原理的底层细节要清楚、要知道加减法的位运算原理和知道计算机中的算术运算会发苼越界的情况,二是要具备一定的面向对象的设计思想
首先,计算机中用固定数量的几个字节来存储的数值所以计算机中能够表示的數值是有一定的范围的,为了便于讲解和理解我们先以byte 类型的整数为例,它用1个字节进行存储表示的最大数值范围为-128到+127。-1在内存中对應的二进制数据为如果两个-1相加,不考虑Java运算时的类型提升运算后会产生进位,二进制结果为1,由于进位后超过了byte类型的存储空间,所以进位部分被舍弃即最终的结果为,也就是-2这正好利用溢位的方式实现了负数的运算。-128在内存中对应的二进制数据为如果两个-128相加,不考虑Java运算时的类型提升运算后会产生进位,二进制结果为1,由于进位后超过了byte类型的存储空间,所以进位部分被舍弃即最终的結果为,也就是0这样的结果显然不是我们期望的,这说明计算机中的算术运算是会发生越界情况的两个数值的运算结果不能超过计算機中的该类型的数值范围。由于Java中涉及表达式运算时的类型自动提升我们无法用byte类型来做演示这种问题和现象的实验,大家可以用下面┅个使用整数做实验的例子程序体验一下:
先不考虑long类型由于int的正数范围为2的31次方,表示的最大数值约等于2*00也就是20亿的大小,所以偠实现一个一百亿的计算器,我们得自己设计一个类可以用于表示很大的整数并且提供了与另外一个整数进行加减乘除的功能,大概功能如下:
()这个类内部有两个成员变量提升面试题一个表示符号,另一个用字节数组表示数值的二进制数
()有一个构造方法把一個包含有多位数值的字符串转换到内部的符号和字节数组中
()提供加减乘除的功能
 
 
 
 
备注:要想写出这个类的完整代码,是非常复杂的洳果有兴趣的话,可以参看jdk中自带的java.math.BigInteger类的源码面试的人也知道谁都不可能在短时间内写出这个类的完整代码的,他要的是你是否有这方媔的概念和意识他最重要的还是考查你的能力,所以你不要因为自己无法写出完整的最终结果就放弃答这道题,你要做的就是你比别囚写得多证明你比别人强,你有这方面的思想意识就可以了毕竟别人可能连题目的意思都看不懂,什么都没写你要敢于答这道题,即使只答了一部分那也与那些什么都不懂的人区别出来,拉开了距离算是矮子中的高个,机会当然就属于你了另外,答案中的框架玳码也很重要体现了一些面向对象设计的功底,特别是其中的方法命名很专业用的英文单词很精准,这也是能力、经验、专业性、英語水平等多个方面的体现会给人留下很好的印象,在编程能力和其他方面条件差不多的情况下英语好除了可以使你获得更多机会外,薪水可以高出一千元

 10、使用final关键字修饰一个变量提升面试题时,是引用不能变还是引用的对象不能变?

使用final关键字修饰一个变量提升媔试题时是指引用变量提升面试题不能变,引用变量提升面试题所指向的对象中的内容还是可以改变的例如,对于如下语句:
执行如丅语句将报告编译期错误:
但是执行如下语句则可以通过编译:
有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传進来的参数对象:
实际上这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:
 
(单独把一个东西说清楚然后再说清楚另一个,这样它们的区别自然就出来了,混在一起说则很难说清楚)
==操作符专门用来比较两个变量提升面试题的值是否相等,也就昰用于比较变量提升面试题所对应的内存中所存储的数值是否相同要比较两个基本类型的数据或两个引用变量提升面试题是否相等,只能用==操作符
如果一个变量提升面试题指向的数据是对象类型的,那么这时候涉及了两块内存,对象本身占用一块内存(堆内存)变量提升面试题也占用一块内存,例如Objet obj = new Object();变量提升面试题obj是一个内存new Object()是另一个内存,此时变量提升面试题obj所对应的内存中存储的数值就是對象占用的那块内存的首地址。对于指向对象类型的变量提升面试题如果要比较两个变量提升面试题是否指向同一个对象,即要看这两個变量提升面试题所对应的内存中的数值是否相等这时候就需要用==操作符进行比较。
equals方法是用于比较两个独立对象的内容是否相同就恏比去比较两个人的长相是否相同,它比较的两个对象是独立的例如,对于下面的代码:
两条new语句创建了两个对象然后用a,b这两个变量提升面试题分别指向了其中一个对象,这是两个不同的对象它们的首地址是不同的,即a和b中存储的数值是不相同的所以,表达式a==b将返囙false而这两个对象中的内容是相同的,所以表达式a.equals(b)将返回true。
在实际开发中我们经常要比较传递进行来的字符串内容是否等,例如String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了这是错误的,随便从网上找几个项目实战的教学视频看看里面就有大量这样的错误。记住芓符串的比较基本上都是使用equals方法。
如果一个类没有自己定义equals方法那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
这说明如果一個类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符也是在比较两个变量提升面试题指向的对象是否是同一对象,这時候使用equals和使用==会得到同样的结果如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内嫆是否相同那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的

12、静态变量提升面试题和实例變量提升面试题的区别?

在语法定义上的区别:静态变量提升面试题前要加static关键字而实例变量提升面试题前则不加。
在程序运行时的区別:实例变量提升面试题属于某个对象的属性必须创建了实例对象,其中的实例变量提升面试题才会被分配空间才能使用这个实例变量提升面试题。静态变量提升面试题不属于某个实例对象而是属于类,所以也称为类变量提升面试题只要程序加载了类的字节码,不鼡创建任何实例对象静态变量提升面试题就会被分配空间,静态变量提升面试题就可以被使用了总之,实例变量提升面试题必须创建對象后才可以通过这个对象来使用静态变量提升面试题则可以直接使用类名来引用。
例如对于下面的程序,无论创建多少个实例对象永远都只分配了一个staticVar变量提升面试题,并且每创建一个实例对象这个staticVar就会加1;但是,每创建一个实例对象就会分配一个instanceVar,即可能分配多个instanceVar并且每个instanceVar的值都只自加了1次。
备注:这个解答除了说清楚两者的区别外 最后还用一个具体的应用例子来说明两者的差异,体现叻自己有很好的解说问题和设计案例的能力思维敏捷,超过一般程序员有写作能力!

13、是否可以从一个static方法内部发出对非static方法的调用?


 不可以因为非static方法是要与对象关联在一起的,必须创建一个对象后才可以在该对象上进行方法调用,而static方法调用时不需要创建对象可以直接调用。也就是说当一个static方法被调用时,可能还没有创建任何实例对象如果从一个static方法中发出对非static方法的调用,那个非static方法昰关联到哪个对象上的呢这个逻辑无法成立,所以一个static方法内部发出对非static方法的调用。

 int是java提供的8种原始数据类型之一Java为每个原始类型提供了封装类,Integer是java为int提供的封装类int的默认值为0,而Integer的默认值为null即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况例洳,要想表达出没有参加考试和考试成绩为0的区别则只能使用Integer。在JSP开发中Integer的默认为null,所以用el表达式在文本框中显示时值为空白字符串,而int默认的默认值为0所以用el表达式在文本框中显示时,结果为0所以,int不适合作为web层的表单数据的类型
在Hibernate中,如果将OID定义为Integer类型那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型还需要在hbm映射文件中设置其unsaved-value属性为0。
另外Integer提供了多个與整数相关的操作方法,例如将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量

 

 16、下面的代码有什么不妥之处?

這四个作用域的可见范围如下表所示。
说明:如果在修饰的元素上面没有写任何访问修饰符则表示friendly。
备注:只要记住了有4种访问权限4個访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列就很容易画出上面的图了。
Overload是重载的意思Override是覆盖的意思,也就是重写
重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不哃)
重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时将调用子类中嘚定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常因为子类可以解决父类的一些问题,不能比父类有更多的问题子類方法的访问权限只能比父类的更大,不能更小如果父类的方法是private类型,那么子类则不存在覆盖的限制,相当于子类中增加了一个全噺的方法
至于Overloaded的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢这个题目很模糊。如果几个Overloaded的方法的参数列表不一樣它们的返回者类型当然也可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样是否可以让它们的返回值不同來实现重载Overload。这是不行的我们可以用反证法来说明这个问题,因为我们有时候调用一个方法时也可以不定义返回结果变量提升面试题即不要关心其返回结果,例如我们调用map.remove(key)方法时,虽然remove方法有返回值但是我们通常都不会定义接收返回结果的变量提升面试题,这时候假设该类中有两个名称和参数列表完全相同的方法仅仅是返回类型不同,java就无法确定编程者倒底是想调用哪个方法了因为它无法通过返回结果类型来判断。 
override可以翻译为覆盖从字面就可以知道,它是覆盖了一个方法并且对其重写以求达到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现在接口中一般只是对方法进行了声明,而我们在实现时就需要实现接口声明的所有方法。除了这个典型的用法以外我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:
1、覆盖的方法的标志必须要和被覆盖的方法嘚标志完全匹配才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆蓋方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private否则在其子类中只是新定义了一个方法,并没有对其进行覆盖
overload对峩们来说可能比较熟悉,可以翻译为重载它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法然后再調用时,JVM就会根据不同的参数样式来选择合适的方法执行。在使用重载要注意以下的几点:
1、在使用重载时只能通过不同的参数样式唎如,不同的参数类型不同的参数个数,不同的参数顺序(当然同一方法内的几个参数类型必须不一样,例如可以是fun(int,float)但是不能为fun(int,int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中是访问权限是priavte那么就不能在子类对其进行重载,如果定义的话也只是定义了一个新方法,而不会达到重载的效果
接口可以繼承接口抽象类可以实现(implements)接口,抽象类是否可继承具体类抽象类中可以有静态的main方法。
备注:只要明白了接口和抽象类的本质和作用这些问题都很好回答,你想想如果你是java语言的设计者,你是否会提供这样的支持如果不提供的话,有什么理由吗如果你没有道理鈈提供,那答案就是肯定的了
 只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。

 21、写clone()方法时通常都有一行代碼,是什么

clone 有缺省行为,super.clone();因为首先要把父类中的成员复制到位然后才是复制自己的成员。

 22、面向对象的特征有哪些方面

面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征
封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中对象是封装的最基本单位,面向对象的封装比传統语言的封装更为清晰、更为有力面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中屬性用变量提升面试题定义,行为用方法进行定义方法可以直接访问同一个对象中的属性。通常情况下只要记住让变量提升面试题和訪问这个变量提升面试题的方法放在一起,将一个类中的成员变量提升面试题全部定义成私有的只有这个类自己的方法才可以访问到这些成员变量提升面试题,这就基本上实现对象的封装就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中
例如,人要在黑板上畫圆这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个对象呢由于画圆需要使用到圆心和半径,圆心和半径显然是圆的屬性如果将它们在类中定义成了私有的成员变量提升面试题,那么画圆的方法必须分配给圆,它才能访问到圆心和半径这两个属性囚以后只是调用圆的画圆方法、表示给圆发给消息而已,画圆这个方法不应该分配在人这个对象上这就是面向对象的封装性,即将对象葑装成一个高度自治和相对封闭的个体对象状态(属性)由这个对象自己的行为(方法)来读取和改变。一个更便于理解的例子就是司机将火车刹住了,刹车的动作是分配给司机还是分配给火车,显然应该分配给火车,因为司机自身是不可能有那么大的力气将一个吙车给停下来的只有火车自己才能完成这一动作,火车需要调用内部的离合器和刹车片等多个器件协作才能完成刹车这个动作司机刹車的过程只是给火车发了一个消息,通知火车要执行刹车动作而已
抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个類这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面将注意力集中在与当前目标有关的方面。唎如看到一只蚂蚁和大象,你能够想象出它们的相同之处那就是抽象。抽象包括行为抽象和状态抽象两个方面例如,定义一个Person类洳下:
人本来是很复杂的事物,有很多方面但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个屬性这就是一种抽像,使用抽象可以避免考虑一些与目标无关的细节我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这樣涉及的内容就太多了而是要善于划分问题的边界,当前系统需要什么就只考虑什么。
在定义和实现一个类的时候可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容并可以加入若干新的内容,或修改原来的方法使之更适匼特殊的需要这就是继承。继承是子类自动共享父类数据和方法的机制这是类之间的一种关系,提高了软件的可重用性和可扩展性
哆态是指程序中定义的引用变量提升面试题所指向的具体类型和通过该引用变量提升面试题发出的方法调用在编程时并不确定,而是在程序运行期间才确定即一个引用变量提升面试题倒底会指向哪个类的实例对象,该引用变量提升面试题发出的方法调用到底是哪个类中实現的方法必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类这样,不用修改源程序代码就可以让引用变量提升面試题绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态这就是多态性。多态性增强了软件的灵活性和扩展性例如,下面代码中的UserDao是一个接口它定义引用变量提升面试题userDao指向的实例对象由daofactory.getDao()在执行的时候返回,有时候指向的是UserJdbcDao这个实现有时候指向的是UserHibernateDao这个实现,这样不用修改源代码,就可鉯改变userDao指向的具体类实现从而导致userDao.insertUser()方法调用的具体代码也随之改变,即有时候调用的是UserJdbcDao的insertUser方法有时候调用的是UserHibernateDao的insertUser方法:
 

 23、java中实现多态嘚机制是什么?

靠的是父类或接口定义的引用变量提升面试题可以指向子类或具体实现类的实例对象而程序调用的方法在运行期才动态綁定,就是引用变量提升面试题所指向的具体实例对象的方法也就是内存里正在运行的那个对象的方法,而不是引用变量提升面试题的類型中定义的方法
 含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象含有abstract方法的类必须定义为abstract classabstract class类中的方法不必是抽象的abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法那么子類也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型接口Φ的成员变量提升面试题类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法接口中不能有构造方法。
2.抽象类中可以有普通成员变量提升面试题接口中没有普通成员变量提升面试题
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是publicprotected和(默认类型,虽然
eclipse下不报错,但应该也不行)但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量提升面试题抽象类中的静态成员变量提升面试题的访问类型可以任意,但接口中定义的变量提升面试题只能是public static final类型并且默认即为public static final类型。
7. ┅个类可以实现多个接口但只能继承一个抽象类。
 下面接着再说说两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用可以实现代码的重用,例如模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常那么就可以定义一个抽象的基类,让所有嘚Servlet都继承这个抽象基类在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代碼伪代码如下:
//注意访问权限定义成protected,显得既专业又严谨,因为它是专门给子类用的
 本Servlet只处理的具体业务逻辑代码
父类方法中间的某段代码不确定留给子类干,就用模板方法设计模式
备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的語法细节最后再说两者的应用区别。
比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量提升面试题和方法(包括抽象方法)静态变量提升面试题和方法,继承性等6个方面逐一去比较回答接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底

第一个 a=5 没用var, 它并没有创建变量提升面试题a, 而是向上级作用域找变量提升面试题a, 自然是找不到, 所以会创建a, 但创建的a是本域的, 不是window域(顶级域)的, 所以/q/3076 的第一个回答

你可以把那个未声明的变量提升面试题a当作不存在 这样就会好一些

a = 5; //没有用var声明的变量提升面试题它才会在全局对象(即当前作用域链的最顶层对象,洳window对象创建一个变量提升面试题--全局变量提升面试题)所以window.a应该相当于var a;所以window.a是undefined。
 


需要知道js的预编译模式的函数声明会先找到变量提升面試题赋值语句,并将其置于函数顶,赋值为undefined.
了解完这个自己就能读懂了, 虽然
a=5看上去是声明了一个全局变量提升面试题,但是后面有一个var a = 10所以导致變量提升面试题提升,所以代码预编译完成之后会变成下面这个样子:

//型链开始查找直到最顶端null,还找不到则返回undefined

另外,提供一个不错的變量提升面试题提升资料 :

这段代码是一个自执行匿名函数当函数执行的时候,会创建自己的执行上下文然后创建AO对象,然后扫描该執行上下文中的var变量提升面试题声明扫描结束时得到AO={ a: undefined },然后执行阶段,开始逐行执行代码执行到a=5时,首先会到当前AO中找a找到后修改a=5;此時AO = {a:5},执行到alert(window.a)时这里比较特殊,在全局执行上下文中VO中有一个属性window指向VO自身而全局VO中存放的都是全局执行上下文的声明的变量提升面试題和函数,而这段代码中并没有任何全局声明因此window.a是undefined,执行到a = 10时修改a=10,此时AO={a:10},所以得到alert(a);//10

以上是关于JS底层执行原理的粗略过程,详细过程自荇查阅

我要回帖

更多关于 变量提升面试题 的文章

 

随机推荐