详细说一下这道js面试题
2016-12-16
今天面试遇到的一个问题,关于js的基本语法问题,因为我做错了,所以这种题目很无聊,额…严肃的说,其实这道题还是考察了挺多东西的,所以还是要拿来说说
先看题目
1 | function Dog() { |
下面代码会输出什么:
1 | a(); |
先来看下这道题考查的点:
- 抗压能力
- 函数式声明提升
- 变量作用域
- 全局变量
- js运算符优先级
- 构造函数
- new关键字
- prototype方法
分析下题目
1 | // 一个构造函数 |
一个一个来
第一题
为了简单说明,下面用a函数输出的数字来代表a分别是哪个a
因为5这个函数式声明,函数式声明会被提前至外部脚本或外部作用域顶部,所以5是最先被定义的
然后来看1里的a,没有var,是全局变量,相当于a在第一行声明,不过因为有5的存在(已经声明并且定义),这个声明就是指向5的
2和3都是Dog的作用域下,和这个无关
代码分析到这里为止的话, a();
结果应该是5
因为4这里a被重新赋值,所以 a();
结果是4
第二题
Dog虽然是构造函数,它也是个函数,但首先它是一个对象
就好比你是小学生,小学生也是学生,但首先你是一个人
所以Dog在这里就是对象,a就是它的一个属性而已,而这个属性是个方法,()执行这个方法,所以结果是2
第三、四题
第三题和第四题问的一样,如果我还是小学生的时候,我就会举手问老师:老师这个题是不是出错了?
但是从以往的面试题来说这里一定是个陷阱,因为a()
执行了一次,再执行一次的话。。。。。。。。。。他妈的不还是一样,函数体内都是写死的东西啊,Dog.a()
同理,不过面试高度紧张的时候,往往就不敢相信这是道送分题啊
第五题
1 | new Dog.a(); |
看到new的时候,Dog作为一个构造函数应该在感慨终于轮到我登场了,然而现实却狠狠的打了它的脸。因为 .
的优先级是高于new
的,
属性访问表达式和调用表达式的优先级比所有的运算符都要高
所以被new的是Dog.a
,而Dog.a
是一个普通的函数,但是我们要知道构造函数是一种约定的名称,事实上任何函数都可以被new出一个对象,只是这种对象没什么卵用
那么久要看new这个过程到底发生了什么, 有兴趣可以参考旧文
这里只说一点,new的时候,被new的函数会执行,所以这就和第二相同,结果是2
第六题
1 | new Dog().a; |
如果没有第五题,这道题没什么特别的,但是经历第五题的各种优先级问题,你会怀疑自己,到底哪个先执行啊
首先()
,[]
,.
这个是最高优先级同级的,谁靠左边,最先执行
所以这里先不管.a
,那么就是new Dog()
,这个的结果是让身为构造函数的Dog表示很欣慰,终于new出个正儿八经的对象了,
这个对象有一个方法,没错就是挂在其构造函数Dog的prototype上的a
所以这个执行的结果是没有console任何东西,这个a还没执行
第七题
1 | new new Dog().a; |
第六题明白了,这道题就是送分题了,再加一个new,优先级当然是在最后了,执行过程同下
1 | new ((new Dog()).a) |
第六题的结果是a这个函数,普通函数呗new,就一定有函数被执行的过程,那么a执行就会打印出3
总结
其实这种问题,做错也没什么,人的记性毕竟有时候就是不太可靠,但是分析过程要懂,说白了就是看着参考答案你要说的出来为什么,如果语法不过关是做不到这点