整理一些有意思的面试题
1
1 | var a = { |
解析
1 | //输出 |
1 - a 和 b指向同一对象
2 - .运算符优先级高于=,所以先计算a.x,
就是给对象添加新属性x,所以 a和b指向的对象{n:1, x:undefined}
3 - 然后计算赋值运算,赋值从右到左,此时a指向一个新对象,a->{ n:2 }
4 - a.x已经执行过了,此时对象的x属性赋值为a,也是指向{ n:2 }
即:
a = {n:2}
b = {n:1,x:{n:2}}
2
1 | console.log(c); |
解析
1 | //输出 |
变量提升也有优先级, 函数声明 > arguments > 变量声明。
3
1 | var name = 'Grace'; |
解析
1 | //输出 |
自执行函数执行时,会先进行变量提升
1 | var name = 'Grace'; |
所以执行的是 if 里面的代码
4
1 | var val = 1; |
解析
1 | //输出 |
当通过 obj.del()调用 del 函数时,del 函数作用域中的 this 绑定为 obj。
在函数作用域中访问 val 时,由于函数中并没有变量 val,因此实际上访问的是全局作用域中的 val,即 1。
5
1 | function A() {} |
解析
1 | //输出 |
var b = new A(); 实例化 b 时,A 的 prototype 为
1 | A.prototype = { |
当访问 b.n 和 b.m 时,通过原型链找到 A.prototype 指向的对象上,即 b.n = 1,b.m = undefined。
var c = new A(); 实例化 c 时,A 的 prototype 为
1 | A.prototype = { |
当访问a.n和a.m时,通过原型链找到A.prototype指向的对象上,此时A.prototype重写,因此a.n = 2,b.m = 3。
6
1 | function Person() { |
解析
1 | //输出 |
Person.getAge();,执行Person函数上的getAge方法,=》20getAge();,执行全局函数,由
变量提升,先是var getAge = undefined,接着function getAge() { console.log(50) };
赋值,执行到var getAge = function () { console.log(40) };
=》40Person().getAge();,执行Person函数,显示改变全局函数getAge=>function () {console.log(10)},
然后返回this,这里的this就是window,
所以window.getAge()=> 10new Person.getAge();,没有参数的new方法,优先级低于.函数,所以先执行Person.getAge,然后实例化这个函数。1
2let b=Person.getAge();
new b() // =>20getAge();,执行全局函数,=》10new Person().getAge();,先执行new Person()实例化Person,接着执行实例的函数,实例上没有该函数,就会执行原型上的函数,就是Person.prototype.getAge = function () { console.log(30) }=>30
7
1 | console.log(false.toString()); |
解析
1 | //输出 |
1.toString(),实际是(1.)toString(),点会被认为是浮点数。如果执行(1).toString()结果就是 1。
同理,5..toString(),第一个点是浮点数,第二个点是函数调用
8
1 | console.log(1 + "2" + "2"); |
解析
1 | //输出 |
重点
+a会把a转换为数字,-a会把a转换成数字的负值(如果不能转换为数字就是NaN)- 字符串与任何值相加都是字符串拼接
1 + -"1" + "2";1+(-1)+'2'=>0+'2'=> ‘02’
9
1 | var x = 1; |
解析
1 | //输出 |
function f(){}当做 if 条件判断,其隐式转换后为true。但是在函数参数不会声明提升,因此 f 函数在外部是不存在的。因此typeof f = ‘undefined’,所以 x += typeof f,相当于 x = x + ‘undefined’为'1undefined'
10
1 | var str = "123abc"; |
解析
1 | 'number' |
使用++运算符时(无论是前置还是后置),如果变量不是数字类型,会首先用Number()转换为数字。因此typeof str++相当于typeof Number(str)++。由于后置的++是先取值后计算,因此相当于 typeof Number('123abc')。即 typeof NaN,所以输出'number'。
11
1 | var x = 10; |
解析
1 | 10 |
JavaScript采用的是词法作用域,规定了函数内访问变量时,查找变量是从函数声明的位置向外层作用域中查找,而不是从调用函数的位置开始向上查找。
