阅读 4563

热乎的前端笔试/面试/跳坑笔记(指南)

写在前面的话

本人不是高手,也是小白一只。在学习的过程中,总是反复的遗忘、记忆、练习、遗忘..因此决定把走过的坑,以及经历的笔试开始慢慢的总结,会不断的更新和添加,原文地址在github,觉得不错的小伙伴,记得给个star哦,共同进步~~

更新地址:传送门

前端面试&笔试&错题指南

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,可以这样子:

    console.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的方法有:

 console.log( bar instanceof Array)  // 如果数组,返回true
 console.log( Array.isArray(bar))  //ES5方法
 console.log( Ojbect.prototype.toString.call(arr) === '[object Array]') 
复制代码
2) 以下两个函数是否等价
function foo1()
{
  return {
      bar: "hello"
  };
}

function foo2()
{
  return
  {
      bar: "hello"
  };
}
复制代码

答案: 不等价!! 注意,第二个函数返回的是undefined

console.log(foo1()); // {bar : "hellp"}
console.log(foo2()); // undefined
复制代码

这也是为什么函数返回对象时,或写大括号时,把{写在一边,因为第二个函数js会默认return后面返回的东西(是空),等价于

return undefined
{xxx}
//后面当然,当然是写了也白写
复制代码
3) NaN是什么?它是什么类型?如何检测一个变量是不是NaN

答案: NaN即Not A Number,但实际上它是Number类型 typeof NaN 将会返回Number。 这个东西比较厉害,因为

NaN === NaN  //false
复制代码

你会发现,它自己都不等于它自己,因此判断变量是否是它,不能使用===。 可以使用isNaN方法

//检查变量是否是nan
isNaN(bar);
Object.is(bar,NaN); //ES6方法,这个方法会修正JS中的一些小bug
复制代码

Object.is()方法,要求严格相等,且Object.is(NaN,NaN)会返回true

2.作用域相关问题

以下程序的输出是什么:

(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这句话,实际上这句话等于

var a; 
b = 3;
复制代码

这样子,实际上,b是声明在了全局变量中(编译器在预编译帮你声明了,然而在严格模式下是不行的) a是局部变量,所以在函数之外是没有定义的。

3.this&对象&数组

1)下面程序输出是什么
var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func:  this.foo = " + this.foo);
        console.log("outer func:  self.foo = " + self.foo);
        (function() {
            console.log(this);
            console.log("inner func:  this.foo = " + this.foo);
            console.log("inner func:  self.foo = " + self.foo);
        }());
    }
};
myObject.func();


//答案
outer func: this.foo = bar
outer func: serl.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar
复制代码

分析: 搞清楚this的指向。记住以下几种规则

  • 谁调用,this指向谁 xxx.fun()
  • new一个对象,this指向实例本身var c = new fun()
  • 使用call/apply/bind修改this指向。

看题目,outer func显然是第一种情况,谁调用,this指向谁,这个时候都是myOjbect。 而在立即执行函数中,在这里this是没有进行绑定指向的,自然从属于window,所以这里this.foo是undefied

补充关于箭头函数的this

function a() {
    return () => {
        return () => {
        	console.log(this)
        }
    }
}
console.log(a()()())
复制代码

注意:箭头函数其实是没有 this 的,这个函数中的 this 只取决于他外面的第一个不是箭头函数的函数的 this。在这个例子中,因为调用 a 符合前面代码中的第一个情况,所以 this 是 window。并且 this 一旦绑定了上下文,就不会被任何代码改变。

2)数组的filter,以下输出结果是什么(2018拼多多前端原题)
var arr = [1,2,3];
arr[10] = 9;
arr.filter((item)=> {
    return item === undefined?
})

//答案
[]
复制代码

解析: 是的,答案的确是[],不是[undefined x 7]。 首先,看下前两句执行后,arr是什么

console.log(arr)
//[1,2,3, emptyx7, 9]
console.log(arr[5])
//undefined
复制代码

从上面结果可以看出,的确中间未定义的(显示为empty的是undefined)。那么,filter之后,不是应该返回为undefined的数据吗?

是的,但是,当数组中都是undefined时,数组就是空,或者说[empty x 7] === []

根据评论小哥哥眷你异次元的废D,这里对解释进行一下更新。实际上empty和undefined是不一样的哦。 引用自国外技术论坛的一段解释如下:

a) It will not crash. The JavaScript engine will make array slots 3 through 9 be “empty slots.”

b) Here, a[6] will output undefined, but the slot still remains empty rather than filled with undefined. This may be an important nuance in some cases. For example, when using map(), empty slots will remain empty in map()’s output, but undefined slots will be remapped using the function passed to it:

var b = [undefined];
b[2] = 1;
console.log(b);             // (3) [undefined, empty × 1, 1]
console.log(b.map(e => 7)); // (3) [7,         empty × 1, 7]
复制代码

翻译过来就是说,undefined和数组保留的empty插槽并不是等同的,即使我们打印出相应的数据会显示undefined,但是与js的undefined是不同的,除了arr.filter,包括arr.map()函数都是会保留empty插槽的。

4. JS小数计算不准确的bug

以下代码返回值是什么

console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);

//答案: 0.30000000000000004
        false
复制代码

解析: 详细的解析见连接,这里说一下解决办法 0.1+0.2 != 0.3

//解决办法
parseFloat((0.1+0.2).toFixed(10));
复制代码

5. 算法/思路相关

1) 讨论实现判断变量是否是整数的函数isInter(x)的实现

答案: 在ES6中,是有现成的方法Number.isInteger可以使用的。如果自己实现,思路是什么呢

//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方法,可以实现以下两种调用方式
console.log(sum(2,3)) //5
console.log(sum(2)(3)) //5
复制代码

答案:

//方法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前端笔试真题)
obj = [
    {id:1,parent:null},
    {id:2,parent:1},
    {id:3,parent:2}
]

obj2 = {
    obj:{
        id: 1,
        parent: null,
        child: {
            id: 2,
            parent: 1,
            child: {
                id: ,3,
                parent: 2
            }
        }
    }
}
复制代码

这一题答案留给小伙伴们思考啦,因为笔者在考试时没有写出很漂亮的程序,就等之后整理后再贴上来,欢迎小伙伴评论区讨论