平时遇到的前端笔试题和面试题

我最近一个多月都在忙着找工作,这些是在面试过程中遇到的一些笔试题和面试题。

1、10 + ‘20’ = ? 再加 ‘20’ 呢?

10 + '20' = '1020' 
'1020' + '20' = '102020'

2、请写出 Ajax 请求中用到的函数

var xhr = new XMLHttpRequest();
xhr.open('GET/POST', 'http://localhost:8080?username=meishadevs', true);
xhr.onreadystatechange = function() {};
xhr.send();

3、使用正则表达式提取出url值为 https://map.baidu.com/x/y/z 中的 map.baidu.com

/https:\/\/([^\/]+)/.exec('https://map.baidu.com/x/y/z')[1]
'https://map.baidu.com/x/y/z'.match(/https:\/\/([^\/]+)/)[1]

执行结果

4、使用ES6的方法实现数组去重

let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];
let set = new Set(array);
let arr = Array.from(set);

5、设计一个函数实现add(3)(4)

function add(a) {
    return function(b) {
        return a + b;
    }
}

add(3)(4)

ES6的写法

add = a => b => a + b
add(3)(4)

对ES6写法做一个变形

add = a => (b => a + b)

再变

add = function (a) {
    return (b => a + b)
}

再变

add = function (a) {
    return function (b) {
        return a + b;
    }
}

6、使用Ajax实现一个表单提交功能,并跳转到提交的地址,(可以使用 jQuery 或 Zepto

7、在完成第6题后使用 Promise 再实现一遍

8、JavaScript中的基本数据类型

Number、String、Boolean、Null、Undefined

9、一道响应式布局的题目

10、call、apply的作用与区别
call 和 apply 都是为了改变函数体内部 this 的指向,它们的第一个参数都是调用函数的对象,call方法接收由若干个参数组成的参数列表,apply方法接收的是一个包含多个参数的数组

例如使用call获取一组数字中的最大值

Math.max.call(null, 1, 3, 5, 8, 2)

例如使用apply获取一组数字中的最大值

Math.max.apply(null, [1, 3, 5, 8, 2])

11、标准盒模型和怪异盒模型的区别
标准盒模型的 box-sizing 属性的值为 content-box
怪异盒模型的 box-sizing 属性的值为 border-box
标准盒模型中 width = 内容的宽度
怪异盒模型中 width = 内容的宽度 + padding + border

12、em 与 rem 的区别
rem 表示根节点(html标签)的字体大小的倍数
当 em 作为 font-size 的单位时,表示相对于父元素的 font-size 值的倍数
当 em作为其他属性单位时,代表自身字体大小的倍数

13、localStorage 与 sessionStorage 的区别
使用 localStorage 保存的数据,除非手动清除,否则会永久保存
使用 sessionStorage 保存的数据仅在当前会话下有效,关闭页面或浏览器后会被清除

14、元素层叠
参考张鑫旭大神的文章:深入理解CSS中的层叠上下文和层叠顺序

15、使用原型现继承

使用 __proto__ 实现继承(不推荐使用这种方式)

//创建animal对象
var animal = {
    name: "animal",

    eat: function () {
        console.log(this.name + " is eating");
    }
};

//创建dog对象
var dog = {
    name: "dog",

    //指向animal对象(dog继承自animal)
    __proto__: animal
};

//创建cat对象
var cat = {
    name: "cat",

    //指向animal对象(cat继承自animal)
    __proto__: animal
};

dog.eat();
cat.eat();

使用 prototype 实现继承

//创建animal对象
var animal = {
    name: "animal",

    eat: function () {
        console.log(this.name + " is eating");
    }
};

//创建构造函数Dog
function Dog() {
    this.name = "dog";
}

//创建构造函数Cat
function Cat() {
    this.name = "cat";
}

//设置Dog的原型为animal(Dog继承自animal)
Dog.prototype = animal;

//设置Cat的原型为animal(Cat继承自animal)
Cat.prototype = animal;

//创建dog对象
var dog = new Dog();

//创建cat对象
var cat = new Cat();

dog.eat();
cat.eat();

16、JavaScript 中事件绑定的方式

button.onclick = function() {}

button.addEventListener("click", function () {});

17、设计一个函数实现判断一个数据的数据类型是不是数组

function isArray(num) {
    return num instanceof Array;
}

18、什么是浏览器的同源策略?
协议相同、域名相同、端口号相同

19、什么是浏览器的标准模式和怪异模式?
参考MDN上的一篇文章:怪异模式和标准模式

20、预处理CSS有什么优点和缺点?
优点:可以实现重用、自动加前缀等
缺点:不能直接识别,需要转换成CSS

21、Web性能优化的手段有哪些?
1、减少HTTP请求数
2、使用CDN
3、给HTTP头部添加过期时间
4、使用Gzip压缩
5、样式表置于页面最前面
6、把JavaScript脚本放在最后面
7、使用外部的JavaScript和CSS
8、压缩JavaScript和CSS
9、如果使用小图标,可以将小图标制成一张雪碧图

22、常见的HTTP状态码有哪些?
参考我网上找到的一篇文章:HTTP常见状态码 200 301 302 404 500 - starof - 博客园

23、下面代码的执行结果

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

输出的结果是 undefined, 2
因为这里存在变量提升,所以上面的代码可以写成下面的形式

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

24、下面代码的输出结果

 var User = {
    count: 1,
    getCount: function () {
        return this.count;
    }
};

var func = User.getCount;
console.log(User.getCount());
console.log(func());

输出的结果是 1, undefined,因为第一个console输出中this指向的是User对象,count是User对象的属性,第二个console输出中this指向的是window对象,window对象中没有count属性,所以输出 undefined

25、如何理解this

1、构造函数中的this指向新创建的实例对象

 function Person(name, age) {
    this.name = name;
    this.age = age;

    this.printThis = function () {
        console.log(this);
    }
}

var person = new Person("meishadevs", 24);
person.printThis();

执行结果

2、普通函数中的this指向函数的调用者

function printThis() {
    console.log(this);
}

printThis();

执行结果

3、自执行函数中的this指向window对象

(function () {
    console.log(this);
})();

执行结果

4、箭头函数中的this指向函数定义时所在的对象

26、写出以字母开头,可以包含字母或数字的4—10位的用户密码的正则表达式

/^[a-zA-Z][a-zA-Z0-9]{3,9}$/.test(password);

27、parent为父级div元素的类名,child为子级div元素的类名,parent和child都不定宽高且parent的宽高都大于child,请写出让child垂直水平居中的CSS

方法一:position + transform

.parent {
    position: relative;
}

.child {
    transform: translate(-50%, -50%);
    position: absolute;
    left: 50%;
    top: 50%;
}

方法二:使用flex布局

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}

28、DOM事件流包括那三个阶段
第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)

29、写出js代码合并下列两个数组,并去重

let arr1 = [2, 6, 1, 3, 8];
let arr2 = [5, 2, 7, 6, 4];

实现代码

let arr1 = [2, 6, 1, 3, 8];
let arr2 = [5, 2, 7, 6, 4];
let arr3 = arr1.concat(arr2);
let set = new Set(arr3);
let arr4 = Array.from(set);
console.log(arr4);

30、下面这段代码的输出结果是,如何使它输出1、2、3、4

for (var i = 1; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    });
}

输出4个5,使用两种方法可以输出1、2、3、4

方法1:使用自执行函数

for (var i = 1; i < 5; i++) {
    (function (num) {
        setTimeout(function () {
            console.log(num);
        });
    })(i);
}

方法2:将var改成let,因为使用var声明的变量没有局部作用域,为了解决这个问题才在ES6中引入了let

for (let i = 1; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    });
}

31、4,4,10,10,加减乘除,怎么出24点?四个数字分别只能用一次

(10 * 10 - 4) / 4

32、如果你有无穷多的水,一个容积为3L的和5L的提桶,你如何准确称出4L的水

第一步:将装5L水的水桶装满                                               
装5L水的水桶中装了5L水 
装3L水的水桶没有装水

   第二步:将装5L水的水桶中的水倒入只能装3L水的水桶中,并倒满只能转3L水的水桶   
装5L水的水桶中装了2L水
装3L水的水桶中装了3L水

第三步:将装3L水的水桶中的水倒掉                                       
装5L水的水桶中装了2L水 
装3L水的水桶为空

第四步:将装5L水的水桶中的2L水倒入装3L水的水桶中                           
装5L水的水桶为空       
装3L水的水桶中装了2L水

第五步:将装5L水的水桶装满                                                
装5L水的水桶中装了5L水
装3L水的水桶中装了2L水

第六步:将装满5L水的水桶中的水倒入装3L水的水桶中,并倒满只能装3L水的水桶    
装5L水的水桶中装了4L水 
装3L水的水桶中装了3L水

33、如何实现快速排序

var quickSort = function (arr) {

    //如果数组中只有一个元素
    if (arr.length <= 1) {

        //直接返回改数组
        return arr;
    }

    //获得数组中中间值的索引(基准的索引)
    var pivotIndex = Math.floor(arr.length / 2);

    //获得数组中的中间值(数组中的基准)
    //并将该值从原数组中删除
    var pivot = arr.splice(pivotIndex, 1)[0];

    //创建数组,用于保存原数组中小于基准的值
    var left = [];

    //创建数组,用于保存原数组中大于基准的值
    var right = [];

    //遍历原数组
    for (var i = 0; i < arr.length; i++) {

        //如果原数组的值小于基准
        if (arr[i] < pivot) {

            //将数组的值保存到left数组中
            left.push(arr[i]);

        //如果原数组的值大于或等于基准
        } else {
            //将数组的值保存到right数组中
            right.push(arr[i]);
        }
    }

    //使用递归不断重复这个过程
    return quickSort(left).concat([pivot], quickSort(right));
};

var array = [85, 24, 63, 45, 17, 31, 96, 50];
console.log('排序前:', array);

var arr = quickSort(array);
console.log('排序后:', arr);

参考链接

meishadevs欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果。
转载请注明: 【文章转载自meishadevs:平时遇到的前端笔试题和面试题

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器