您当前的位置:首页 > 计算机 > 编程开发 > Html+Div+Css(前端)

前端面试笔试题分享

时间:12-14来源:作者:点击数:
CDSY,CDSY.XYZ

第一题

    console.log(a)       //       undefined
    var a = 1;
    var getNum = function() {
        a = 2;
    }
    function getNum() {
        a = 3;
    }
    console.log(a)      //        1
    getNum()
    console.log(a)      //        2

这道题主要考查声明提升函数声明先于变量声明这两个知识点。在解析这个js片段的时候是按照这样的顺序:

// 声明提升
function getNum() {
    a = 3;
}
var a;
var getNum;

// 
console.log(a);
a = 1;
getNum = function() {
    a = 2;
}
console.log(a)
getNum()
console.log(a)

这样就很清晰了,第一次输出a的时候还没有赋值,所以是 undefined。第二次的不用说了。第三次输出2是因为,一开始 getNum 是指向一个函数的,后来又声明赋值成了一个函数表达式。

第二题

// 每隔一秒输出一次i值
for(var i = 0; i < 5; i++){
    // TODO
}

此题主要考查闭包和 js 执行机制。以下几种解法:

大概1秒输出一次的版本:

// 利用立即执行函数形成闭包
(function(i){
    setTimeout(function() {
        console.log(i)
}, i * 1000)})(i)
// 利用setTimeout的第三个参数形成闭包
setTimeout(function(i) {
    console.log(i)
}, i * 1000, i)
// 如果不是题目中指定了var,利用ES6的let就简单多了
for(let i = 1; i < 5; i++) {
    setTimeout(function(){
        console.log(i)
    }, i * 1000)
}
// 再看ES7版本
const sleep = (time) => 
    new Promise((resolve, reject) => 
        setTimeout(resolve, time));
(async function(){
   for(let i=0;i<10;i++){
       await sleep(1000);
       console.log(i);
   }
})()

之所以是说是大概,是因为 setTimeout 并不是延时多少秒后执行函数,而是多少秒后把函数扔进事件队列中等待执行,如果此时队列里有其他任务 的话那就不是精确的1秒了。

再看比较精确的1秒版本:

for(var i =0; i < 5; i++) {
    var time = new Date();
    while(new Date() - time < 1000) {
    }
    console.log(i)
}

直接阻塞线程一秒钟,简单粗暴有木有~

第三题

var a = {}
var b = {
    key: "a" 
}
var c = {
    key: "c"
}

a[b] = "123";
a[c] = "456";

console.log(a[b])  // 456

这题主要考查对象。其实这里 a[b] 和 a[c] 中的 b、c 都会调用 object.prototype.toString(),都变成了 [object Object],这样就与对象中的 key 值无关了。所以 a[b] 和 a[c] 的指向是相同的。

第四题

var f = function() {
    var c = "ccc";
    return {
        a: function() {
            return c;
        },
        b: function(d) {
            c = d;
        }
    }
}()

console.warn(f.a())         // ccc
console.warn(f.c)           // undefined
console.warn(f.b("www"))    // undefined
console.warn(f.a())         // www

这题主要考查的是执行上下文中的作用域链。我们要注意到函数表达式后的那个函数执行符——(),它是个立即执行函数,也就是说 f 是个包含 a、b 属性的对象。

console.warn(f.a()) 

当 a() 的执行上下文被激活时,作用域和变量对象被确定,c 是个自由变量,需要在作用域链中向上查找,然受在父级作用域中找到,所以输出 ccc。

console.warn(f.c)

这个就不用说啦,f中没有c这个属性,取不到当然返回 undefined

console.warn(f.b("www"))

同第一行一样,修改的是父级作用域中的 c,但由于没有返回值所以输出的是 undefined。

第五题

数组去重 输入 [1,2,3,1,'1','2',2] 返回 [1,2,3,'1','2']。 这个嘛方法就很多啦。

(function(arr){
    console.log([...(new Set(arr))])
})([1,2,3,1,'1','2',2])

第六题

有两个小写字符串 s1、s2,s2 是 s1 经过打乱后增加一个小写字符得到的, 编程得出 s2 中增加的字符,算法时间复杂度最好接近 O(n) ,如 s1 是 abc , s2 是 cbad ,那么增加的字符为 d。

笔者关于这道题的思考,首先是考虑到增加的字符可能是 s1 中已经存在的,那通过遍历+indexOf() 的方案也就没用了,所以笔者在写这道题的时候考虑到 s1、s2 只有一个字符之差,索性把 s1、s2 中的字符都填入一个对象中统计每个字符的个数,个数为奇数的就是那个多出来的字符了。上代码:

var s1 = "aaabweddccc";
var s2 = "aaaewwbcccdd";
(function(a,b){
    let aLen = a.length;
    let bLen = b.length;            
    let hash = {};
    for(let i = 0; i < aLen; i++) {
        hash[a[i]] ? hash[a[i]]++ : hash[a[i]] = 1;
        hash[b[i]] ? hash[b[i]]++ : hash[b[i]] = 1;               
    } 
    hash[b[aLen]] ? hash[b[aLen]]++ : hash[b[aLen]] = 1; 
    console.log(hash)                          
    for(let j in hash) {
        if(hash[j] % 2 !== 0) {
            console.log(j) 
        }
    }
})(s1,s2)
CDSY,CDSY.XYZ
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐