这个系列主要是对自己秋招以来,笔试、面试过程中的问题进行记录和解决,希望自己能够”吃一堑长一智”
系列笔记:
参考资料:37 Essential JavaScript Interview Questions
有很多内容来自以上参考,真的可以说是非常经典了!
Css相关
1. display:none与visibility:hidden的区别(2018拼多多前端笔试真题)
答案:在视觉效果上,两者是相同的,但是对于操作dom上是不同的 。
dispaly:none 会让dom的整个宽、高等相关位置元素失效,整个消失;
visibility:hidden 只是让该元素不可见,但是width以及原有位置是不会改变的
javascript
1. 基本问题
1) 是否可以使用 typeof bar === 'object'
来检测bar是不是object类型,有和风险?
答案: 有风险,js的基本数据类型有 String
Number
Boolean
undefined
null
和一种复杂数据类型object
(ES6新增了symbol
)。
对于复杂数据类型object
,其实typeof null
返回的也是object
,因为本质上null
就是一个占位用的对象。另一方面,数组Array
也不能用typeof
检测数据类型,因为同样会返回object
。
因此,如果想要检测bar
是不是object
,可以这样子:1
2
3console.log((bar !== null) && (tiopnuiop[yuiop[]\\]poi456/ypeof bar ==='object'))
//当然,如果认为function也是 object,可以用下面的语句
console.log((bar !== nul)&& (typeof bar ==='object')||(typeof bar ==='function'))
除此以外,还有比如Array的情况,因为Array也会返回object
,如果我们不像让Array被认为是Object,就必须真正的认清Array,人情Array的方法有:1
2
3console.log( bar instanceof Array) // 如果数组,返回true
console.log( Array.isArray(bar)) //ES5方法
console.log( Ojbect.prototype.toString.call(arr) === '[object Array]')
2) 以下两个函数是否等价
1 | function foo1() |
答案: 不等价!!
注意,第二个函数返回的是undefined
1
2console.log(foo1()); // {bar : "hellp"}
console.log(foo2()); // undefined
这也是为什么函数返回对象时,或写大括号时,把{
写在一边,因为第二个函数js会默认return后面返回的东西(是空),等价于1
2
3return undefined
{xxx}
//后面当然,当然是写了也白写
3) NaN
是什么?它是什么类型?如何检测一个变量是不是NaN
?
答案: NaN即Not A Number
,但实际上它是Number
类型typeof NaN
将会返回Number
。
这个东西比较厉害,因为1
NaN === NaN //false
你会发现,它自己都不等于它自己,因此判断变量是否是它,不能使用===
。
可以使用isNaN方法1
2
3//检查变量是否是nan
isNaN(bar);
Object.is(bar,NaN); //ES6方法,这个方法会修正JS中的一些小bug
Object.is()方法,要求严格相等,且Object.is(NaN,NaN)会返回true
2.作用域相关问题
以下程序的输出是什么:1
2
3
4
5(function(){
var a = b = 3;
})();
console.log("a defined? " + (typeof a !== 'undefined'));
console.log("b defined? " + (typeof b !== 'undefined'));
答案:
a defined? false
b defined? true
理解这道题的核心在于如何理解var a = b = 3
这句话,实际上这句话等于1
2var a;
b = 3;
这样子,实际上,b是声明在了全局变量中(编译器在预编译帮你声明了,然而在严格模式下是不行的)
a是局部变量,所以在函数之外是没有定义的。
3.this&对象&数组
1)下面程序输出是什么
1 | var myObject = { |
分析: 搞清楚this的指向。记住以下几种规则
- 谁调用,this指向谁
xxx.fun()
- new一个对象,this指向实例本身
var c = new fun()
- 使用call/apply/bind修改this指向。
看题目,outer func
显然是第一种情况,谁调用,this指向谁,这个时候都是myOjbect。
而在立即执行函数中,在这里this是没有进行绑定指向的,自然从属于window,所以这里this.foo是undefied
补充关于箭头函数的this1
2
3
4
5
6
7
8function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
注意:箭头函数其实是没有 this 的,这个函数中的 this 只取决于他外面的第一个不是箭头函数的函数的 this。在这个例子中,因为调用 a 符合前面代码中的第一个情况,所以 this 是 window。并且 this 一旦绑定了上下文,就不会被任何代码改变。
2)数组的filter,以下输出结果是什么(2018拼多多前端原题)
1 | var arr = [1,2,3]; |
解析: 是的,答案的确是[],不是[undefined x 7]
。
首先,看下前两句执行后,arr是什么1
2
3
4console.log(arr)
//[1,2,3, emptyx7, 9]
console.log(arr[5])
//undefined
从上面结果可以看出,的确中间未定义的(显示为empty的是undefined)。那么,filter之后,不是应该返回为undefined
的数据吗?
是的,但是,当数组中都是undefined时,数组就是空,或者说[empty x 7] === []
4. JS小数计算不准确的bug
以下代码返回值是什么1
2
3
4
5console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);
//答案: 0.30000000000000004
false
解析: 详细的解析见连接,这里说一下解决办法 0.1+0.2 != 0.31
2//解决办法
parseFloat((0.1+0.2).toFixed(10));
5. 算法/思路相关
1) 讨论实现判断变量是否是整数的函数isInter(x)
的实现
答案: 在ES6中,是有现成的方法Number.isInteger
可以使用的。如果自己实现,思路是什么呢1
2
3
4
5
6
7
8
9
10//1 异或运算
function isInter(x) {
return x ^ 0 === x
}
//2 取整
return Math.round(x) === x //同样可以用floor ceil
//取余
return (typeof x === 'number')&&(x % 1 === 0)
2) 写一个sum方法,可以实现以下两种调用方式
1 | console.log(sum(2,3)) //5 |
答案:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//方法1
var sum = function(x,y) {
if(y === undefined) {
return function(y) {
return x + y;
}
}else {
return x + y;
}
}
//方法2
var sum = function(x){
if( arguments.length === 1) {
return function (y) {
return x + y;
}
} else {
console.log('here');
return arguments[0] + arguments[1];
}
}
3) 使用递归的方法,将obj变为obj2的格式(拼多多2018前端笔试真题)
1 | obj = [ |