欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端面试题(面试的回答和学习面试题)

程序员文章站 2022-06-09 18:47:43
...

对于技术来说,面试题这的是一个有意思的东西,被技术大牛面试过后真的让你受益匪浅。在渣渣大牛面试过后那叫一个搞笑和装逼(边面试边给你讲,主要讲的都不对,整的有点耐人寻味skr)。但是,虽然那些渣渣大牛们面试问的问题觉得很脑残,但是面试题真的算是一个武功秘籍,不能因为渣渣大牛们的面试而怀疑面试题,因为渣渣们面试问的那不叫面试题。

ok 开始我们的面试题吧(以下都是个人的整理,回答面试题和学习面试题,会持续的更新滴,建议先看右下角的目录,比较多)

一、关于HTML的面试题

1、html5哪些操作可以SEO优化

  • title标签;meta标签;header标签;footer标签
    元标签(meta标签);
  • 导航标签(nav标签);文章标签(article标签);左或右侧标签(aside标签)

2、页面导入样式时,使用link和@import有什么区别?

  • 1.link属于HTML标签,除了加载CSS外,还能用于定义RSS,定义rel连接属性等作用;而@import是CSS提供,只能加载CSS;
  • 2.页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
    import是CSS2.1提出的,只在IE5以上才能被识别,而link是HTML标签,无兼容问题;

3、行内元素和块状元素的区别?行内快元素的兼容性使用?(IE8以下)

  • 行内元素:会在水平方向排列,不能包含快级元素,设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效
  • 块级元素:各占据一行,垂直方向排列。从新行开始结束接着一个断行
    兼容性:display:inline-block;display:inline;zoom:1;

ok 关于html的面试题个人觉得有用的并不多,然后什么doctype的意义,HTML5带来了哪些变化?,html,xhtml,html5之间有什么关系?我觉得正常的面试官不会问你这些的,这也不是重头,先热热身,那我们继续!

二、关于CSS的面试题(持续更新中。。。)

1、如何清除浮动,以及清除浮动的方法

  • 1)添加额外标签
    在浮动元素末尾添加一个空的标签例如

    ,其他标签br等亦可。

    <div class="warp" id="float">
        <h2>1)添加额外标签</h2>
        <div class="main left">.main{float:left;}</div>
        <div class="side left">.side{float:right;}</div>
        <div style="clear:both;"></div>
    </div>
    

    优点:通俗易懂,容易掌握

    缺点:可以想象通过此方法,会添加多少无意义的空标签,有违结构与表现的分离。

  • 2)父元素设置 overflow:hidden
    通过设置父元素overflow值设置为hidden;在IE6中还需要触发 hasLayout ,例如 zoom:1;

    <div class="warp" id="float" style="overflow:hidden; *zoom:1;">
        <h2>2)父元素设置 overflow </h2>
        <div class="main left">.main{float:left;}</div>
        <div class="side left">.side{float:right;}</div>
    </div>
    

    优点:不存在结构和语义化问题,代码量极少

    缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素;

  • 3)父元素设置 overflow:auto 属性
    同样IE6需要触发hasLayout,演示和2差不多

    优点:不存在结构和语义化问题,代码量极少

    缺点:多个嵌套后,firefox某些情况会造成内容全选;IE中 mouseover 造成宽度改变时会出现最外层模块有滚动条等,firefox早期版本会无故产生focus等。

  • 4)使用:after 伪元素

    需要注意的是 :after是伪元素,不是伪类(某些CSS手册里面称之为“伪对象”),很多闭合浮动大全之类的文章都称之为伪类,不过csser要严谨一点,这是一种态度。由于IE6-7不支持:after,使用 zoom:1触发 hasLayout。

    .clearfix:before{ content:'';display:table; }
    .clearfix:after {content:""; display:block; height:0; visibility:hidden; clear:both; }
    
    /* 简洁写法 */
    .clearfloat:after{display:block;clear:both;content:'';}
    

    优点:结构和语义化完全正确,代码量居中
    缺点:复用方式不当会造成代码量增加

  • 小结

    通过对比,我们不难发现,其实以上列举的方法,无非有两类:

    其一,通过在浮动元素的末尾添加一个空元素,设置 clear:both属性,after伪元素其实也是通过 content 在元素的后面生成了内容为一个点的块级元素;

    其二,通过设置父元素 overflow。

    面试的时候的时候面试官跟想听到伪类的方法

2、说说flex布局

内容太多,彻底学习去这里:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

  • 面试重点回答需要知道这些,平时开发这些用的的最多

    怎么横向居中?justify-content-属性定义了项目在主轴上的对齐方式。

    .box {
    justify-content: flex-start | flex-end | center | space-between | space-around;
    }
    

    怎么竖向居中?align-items-属性定义项目在交叉轴上如何对齐。

    .box {
    align-items: flex-start | flex-end | center | baseline | stretch;
    }
    

    align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

    .box {
    align-content: flex-start | flex-end | center | space-between | space-around | stretch;
    }
    

3、垂直居中的方法

  • margin:0 auto;
  • justify-content: center;
  • text-algin:center

4、水平居中的方法

  • flex布局的align-items: center或者margin:auto;
  • position: absolute;top: calc( 50% -需要居中的一般高度);

平时用的一些小技巧样式(项目一定会用到但用的很少,还不能忘)

1、p标签段落前面缩进

p{text-indent:2em}

2、ul去掉前面的点

ul{list-style:none}

关于JS的面试题(持续更新中。。。)

1、数据类型和引用类型/javascript的typeof返回哪些数据类型,参考地址

  • 基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值。
  • 引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)

2、JS中深克隆和浅克隆详解,参考地址

  • 浅复制(浅克隆):直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址
  • 深复制(深克隆):就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。深拷贝,是拷贝对象各个层级的属性

2.1浅克隆

  • 1.基本数据类型的赋值(以String为例)
    let a = "hello world";
    let b = a;
    alert( b ); // 'hello world'
    a = "changed";
    alert( b ); // 'hello world'
    
    // 在这段代码中,把a赋值给b,当a的值发生变化时,并不影响b
    
  • 2引用数据类型的赋值(以Array为例)
    let arr1 = [1, 2, 3, 4];
    let arr2 = arr1;
    console.log( arr2 );  // [10, 2, 3, 4]
    arr1[0] = 10;
    console.log( arr2 );  // [10, 2, 3, 4]
    
    // 在这段代码中,把arr1赋值给arr2,当arr1的值改变时,arr2对应的值也会改变
    

对以上两个例子的分析

对于基本数据类型而言,把a的值赋值给b后,a的修改,不会影响到b

对于引用数据类型而言,把arr1赋值给arr2后,arr1的修改,会影响到arr2对应的值

基本数据类型是直接存储在 栈内存 中的,而引用数据类型,则仅仅是把地址存储在 栈内存 中,真正的数据是存储在 堆内存 中的,赋值操作时,仅仅把地址进行了赋值。

2.2 实现深克隆的方式

  • 方法一: 递归

    function deepClone( obj ){
        let objClone = Array.isArray(obj) ? [] : {};
        if( obj && typeof obj==="object"){
            for(key in obj){
                if(obj.hasOwnProperty(key)){
                    if(obj[key]&&typeof obj[key] ==="object"){
                        objClone[key] = deepClone(obj[key]);
                    }else{
                        objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone;
    }    
    let a=[1,2,[2, 3],4],
        b=deepClone(a);
    a[2][0]=10;
    console.log(a,b);
    
  • 方法二: JSON.stringify 和 JSON.parse

    function deepClone(obj){
        let _obj = JSON.stringify(obj),
            objClone = JSON.parse(_obj);
        return objClone
    }    
    let a=[0,1,[2,3],4],
        b=deepClone(a);
    a[0]=1;
    a[2][0]=1;
    console.log(a,b);
    
  • 方法三: jQuery中的 $.extend

    let a=[0,1,[2,3],4],
        b=$.extend(true,[],a);
    a[0]=1;
    a[2][0]=1;
    console.log(a,b);
    

    $.extend( [deep ], target, object1 [, objectN ] )

    deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

    target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。

    object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

  • 方法四:var newArray = Array.slice(0) 用来生成新得数组

    这个是vue源码中生成新数组的方法,偷偷学到的

3、js 宏任务和微任务,参考地址

宏任务(macrotask )和微任务(microtask )

macrotask 和 microtask 表示异步任务的两种分类。

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

把下面的代码运行一下,加速你的理解:

//主线程直接执行
console.log('1');
//丢到宏事件队列中
setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
//微事件1
process.nextTick(function() {
    console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    //微事件2
    console.log('8')
})
//丢到宏事件队列中
setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

4、重写js push函数(因为vue2.+的object.defineproperty中重写了push、pop、unshift、shift、reverse、sort)

let _push = Array.prototype.push
Array.prototype.push = function(){
    for(let i of arguments){
        _push.call(this, i);
    }
    // _push.call(this, arguments);
    // console.log('参数为', arguments);
    console.log('this', this);
}

let a = [1,2,3]
a.push(4,5)

5、this(this的4种指向和改变this指向的方式),参考地址和apply、call、bind区别、用法,参考地址

6、从输入URL到页面呈现的过程,参考地址

7、split() join() 的区别

  • 前者是将字符串切割成数组的形式,后者是将数组转换成字符串

8、数组方法pop() push() unshift() shift()

  • push()尾部添加 pop()尾部删除 unshift()头部添加 shift()头部删除

9、闭包是什么,有什么特性,对页面有什么影响

  • 闭包就是能够读取其他函数内部变量的函数,使得函数不被GC回收,如果过多使用闭包,容易导致内存泄露

10、如何阻止事件冒泡

  • ie:阻止冒泡ev.cancelBubble = true;非IE ev.stopPropagation();

11、如何阻止默认事件

  • (1)return false;(2) ev.preventDefault();

12、事件委托是什么

  • 利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!

13、Javascript的事件流模型都有什么?

  • “事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播

  • “事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的

  • “DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡

14、回答以下代码,alert的值分别是多少?

<script>
     var a = 100;  
     function test(){  
        alert(a);  
     a = 10;  //去掉了var 就变成定义了全局变量了
        alert(a);  
}  
test();
alert(a);
</script>
正确答案是: 1001010

15、判断 js 类型的方式

  • 1、typeof
    可以判断出’string’,‘number’,‘boolean’,‘undefined’,‘symbol’
    但判断 typeof(null) 时值为 ‘object’; 判断数组和对象时值均为 ‘object’

  • 2、instanceof
    原理是 构造函数的 prototype 属性是否出现在对象的原型链中的任何位置

    function A() {}
    let a = new A();
    a instanceof A     //true
    //因为 Object.getPrototypeOf(a) === A.prototype;
    
    1. Object.prototype.toString.call()
      常用于判断浏览器内置对象,对于所有基本的数据类型都能进行判断,即使是 null 和 undefined
    1. Array.isArray()
      用于判断是否为数组

16、统计字符串中字母个数

	var str = "I think javascript is good";
	//解:方法不唯一        
	str = str.toLowerCase();
    var result = {};
    for(var i in str) {
        if(str[i] in result) { 
            result[str[i]]++;
        } else { 
            result[str[i]] = 1;;
        }
    }

17、给数组去重

var arrays = [1,2,3,2,4,6,5,7]
	function unique (arrray) {
		var result=[]
		//请编程实现数组去重
		return result;
	}	

	//1.利用es6的set对象
 		result = [...new Set(array)];//[...new  Set (array)]
	//2.利用对象属性的唯一性
		let obj = {};
        for (let i of array) {
           	if (!obj[i]) {
               	result.push(i);
               	obj[i]=1;
            }
        }
	//3.利用sort方法排序去重
		var newarray = array.sort();
        result = [newarray[0]];
        var length = newarray.length;
        for( var i = 1 ;i<length; i++) {
            newarray[i] !== newarray[i-1] && result.push(newarray[i]);
        }	
	//4.利用for...of+includes()循环
		for(var i of array) {
           	!result.includes(i) && result.push(i);
        }
	//5.用filter结合indexOf
	 	result = array;
        return result.filter((item, index)=> {
            return result.indexOf(item) === index
        })
	//6.利用双层for循环(6分)类似
		var length = array.length;
        for(var i =0; i<length; i++) {
            var only = true;
            for(var j =i+1; j<length; j++){
                if(!only) continue;
                if(array[i] == array[j])  only = false; 
            }
           	if(only) result.push(array[i]);
        }

18、js中forEach,for in,for of循环的用法,参考地址