前端面试题(总结)

一、 CSS/HTML部分
1.请说出px,em,rem的区别

  1. px是固定长度单位,不随其它元素的变化而变化
  2. em和%是相对于父级元素的单位,会随父级元素的属性(font-size或其它属性)变化而变化
  3. rem是相对于根目录(HTML元素)的,所有它会随HTML元素的属性(font-size)变化而变化
  4. px和%用的比较广泛一些,可以充当更多属性的单位,而em和rem是字体大小的单位,用于充当font-size属性的单位
  5. 一般来说:1em = 1rem = 100% = 16 px

2.解释css sprites并说出为什么要使用css sprites

CSSSprites在国内很多人叫css精灵,是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不会像以前那样一幅一幅地慢慢显示出来了。对于当前网络流行的速度而言,不高于200KB的单张图片的所需载入时间基本是差不多的,所以无需顾忌这个问题。

CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字精确的定位出背景图片的位置。

  1. 利用CSS Sprites能很好地减少网页的http请求,从而大大的提高页面的性能,这也是CSS Sprites最大的优点,也是其被广泛传播和应用的主要原因;
  2. CSS Sprites能减少图片的字节,曾经比较过多次3张图片合并成1张图片的字节总是小于这3张图片的字节总和。
  3. 解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命名就可以了,不需要对每一个小元素进行命名,从而提高了网页的制作效率。
  4. 更换风格方便,只需要在一张或少张图片上修改图片的颜色或样式,整个网页的风格就可以改变。维护起来更加方便。
    缺点:
  5. 在图片合并的时候,你要把多张图片有序的合理的合并成一张图片,还要留好足够的空间,防止板块内出现不必要的背景;这些还好,最痛苦的是在宽屏,高分辨率的屏幕下的自适应页面,你的图片如果不够宽,很容易出现背景断裂;
  6. CSS Sprites在开发的时候比较麻烦,你要通过photoshop或其他工具测量计算每一个背景单元的精确位置,这是针线活,没什么难度,但是很繁琐;
  7. CSS Sprites在维护的时候比较麻烦,如果页面背景有少许改动,一般就要改这张合并的图片,无需改的地方最好不要动,这样避免改动更多的css,如果在原来的地方放不下,又只能(最好)往下加图片,这样图片的字节就增加了,还要改动css。

3.简述你对HTML语义化的理解

a. 为了在没有CSS的情况下,页面也能呈现出很好地内容结构、代码结构:为了裸奔时好看;
b. 用户体验:例如title、alt用于解释名词或解释图片信息的标签尽量填写有含义的词语、label标签的活用;
c. 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;
d. 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以有意义的方式来渲染网页;
e. 便于团队开发和维护,语义化更具可读性,遵循W3C标准的团队都遵循这个标准,可以减少差异化。

4.页面引入css的方法有哪些?link和@import的区别是什么?

1.行内式
行内式是在标记的style属性中设定CSS样式。这种方式没有体现出CSS的优势,不推荐使用。
2.嵌入式
嵌入式是将CSS样式集中写在网页的标签对的标签对中。格式如下:

     <head>

    <style type="text/css">

           ...此处写CSS样式

   </style>

  </head>

缺点是对于一个包含很多网页的网站,在每个网页中使用嵌入式,进行修改样式时非常麻烦。单一网页可以考虑使用嵌入式。

3.导入式
将一个独立的.css文件引入HTML文件中,导入式使用CSS规则引入外部CSS文件,

4.链接式
也是将一个.css文件引入到HTML文件中,但它与导入式不同的是链接式使用HTML规则引入外部CSS文件,它在网页的标签对中使用标记来引入外部样式表文件,使用语法如下:

      <link href="mystyle.css" rel="stylesheet" type="text/css"/>

使用链接式时与导入式不同的是它会以网页文件主体装载前装载CSS文件,因此显示出来的网页从一开始就是带样式的效果的,它不会象导入式那样先显示无样式的网页,然后再显示有样式的网页,这是链接式的优点。

总结:一般来说,做网站时把样式多写在多个样式表文件中,因此我们先用链接式引入一个总的CSS文件,然后在这个CSS文件中在使用导入式来引入其他的CSS文件。但如果通过JavaScrip来动态引入CSS文件则只能使用链接式。

5.iframe会阻塞页面的加载吗?如果iframe使得onload事件不能及时触发,解决的方法有哪些?

不会阻塞页面的加载,因为它可以与主页面并行加载。
iframe会阻塞主页面的onload事件

主页面和iframe共享同一个连接池
友好型iframe加载
这是用来加载广告的。虽然这不是一种iframe的加载技术,但是是用iframe来盛放广告的。他的亮点不在于iframe如何加载,而是主页面、iframe、广告如何协同工作的。
如下:
先创建一个iframe。
设置他的src为一个相同域名下的静态html文件在这个iframe里面,
设置js变量inDapIF=true来告诉广告它已经加载在这个iframe里面了在这个iframe里面,创建一个script元素加上广告的url作为src,
然后像普通广告代码一样加载当广告加载完成,
重置iframe大小来适应广告这种方法也没有浏览器的兼容性问题。

<script>
 (function(d) {
    var iframe = d.body.appendChild(d.createElement('iframe')),
    doc = iframe.contentWindow.document; 
    // style the iframe with some CSS     iframe.style.cssText ="position:absolute;width:200px;height:100px;left:0px;"; 
    doc.open().write('<body οnlοad="'+   'var d = document;d.getElementsByTagName(\'head\')[0].'+   'appendChild(d.createElement(\'script\')).src'+'=\'\/path\/to\/file\'">');
    doc.close(); //iframe onload event happens 
  })(document);
 </script>

6.html5新增的本地存储是什么?他们之间的区别以及和cookie的区别是什么?

sessionStorage:数据保存在session 对象中(临时)

localStorage:数据保存在本地硬件设备中(永久)

区别在于localSorage是永久保存,而sessionStorage会在浏览器关闭时自动清除。sessionStorage可以用来暂时保存登陆后的用户名等信息。
cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。

区别:
1、 cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。

2、 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

3、 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。

4、 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

7.用两种方法实现div水平居中,html结构如下:


<div class="wrapper">
	<div class="content"></div>
</div>

方法1:
.content{
	margin: 0 auto
}
方法2:
给要水平居中的div设置属性:width    height      position       left      margin-left     
其中left:50%    position:的值除了static之外的都可以   marin-left:的值为负数,数值大小为width的一半

.content{
			position:relative;
			left:50%;
			width:400px;
			height:400px;
			margin-left:-200px;
		    background-color:red;
		    display: block;
}

8.position属性的值有哪些?他们的区别是什么?

  1. position: relative;相对定位
    1> 不影响元素本身特性(无论区块元素还是内联元素会保留其原本特性)
    2> 不会使元素脱离文档流(元素原本位置会被保留,即改变位置也不会占用新位置
    3> 没有定位偏移量时对元素无影响(相对于自身原本位置进行偏移)
    4>提升层级(用z-index样式的值可以改变一个定位元素的层级关系,从而改变元素的覆盖关系,值越大越在上面,z-index只能在position属性值为relative或absolute或fixed的元素上有效。) (两个都为定位元素,后面的会覆盖前面的定位)
  2. position: absolute;绝对定位
    1> 使元素完全脱离文档流(在文档流中不再占位)
    2> 使内联元素在设置宽高的时候支持宽高(改变内联元素的特性)
    3> 使区块元素在未设置宽度时由内容撑开宽度(改变区块元素的特性)
    4> 相对于最近一个有定位的父元素偏移(若其父元素没有定位则逐层上找,直到document——页面文档对象)
    5> 相对定位一般配合绝对定位使用(将父元素设置相对定位,使其相对于父元素偏移)
    6> 提升层级(同相对定位)
  3. position: fixed;固定定位
    fixed生成固定定位的元素,相对于浏览器窗口进行定位。
  4. position:static:默认值默认布局。
    元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。
  5. position: sticky 粘性定位粘性定位,
    该定位基于用户滚动的位置。它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。注意: Internet Explorer, Edge 15 及更早 IE 版本不支持 sticky 定位。 Safari 需要使用 -webkit- prefix 。
  6. position: inherit规定应该从父元素继承 position 属性的值。
  7. posiyion: initial 设置该属性为默认值,
    详情查看CSS initial 关键字initial 关键字用于设置 CSS 属性为它的默认值。initial 关键字可用于任何 HTML 元素上的任何 CSS 属性。

9.用css写一个纯三角形

div {
    width: 0;
    height: 0;
    border-width: 0 40px 40px;
    border-style: solid;
    border-color: transparent transparent red;
}

10 ::before和:after中双冒号和单冒号有什么区别?解释一下这2个伪元素的作用
区别:
单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。(伪元素由双冒号和伪元素名称组成)
双冒号是在当前规范中引入的,用于区分伪类和伪元素。不过浏览器需要同时支持旧的已经存在的伪元素写法,
比如:first-line、:first-letter、:before、:after等,
而新的在CSS3中引入的伪元素则不允许再支持旧的单冒号的写法。

想让插入的内容出现在其它内容前,使用::before,否者,使用::after;
在代码顺序上,::after生成的内容也比::before生成的内容靠后。
如果按堆栈视角,::after生成的内容会在::before生成的内容之上
11.img中alt和title的区别
alt属性是在你的图片因为某种原因不能加载时在页面显示的提示信息,它会直接输出在原本加载图片的地方,而title属性是在你鼠标悬停在该图片上时显示一个小提示,鼠标离开就没有了,有点类似jQuery的hover,你可以自己试试,另外,HTML的绝大多数标签都支持title属性,title属性就是专门做提示信息的
12.vue中v-if和v-show的区别
1.手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;
2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
5.使用场景:v-if适合运营条件不大可能改变;v-show适合频繁切换。

13.vue中created与mounted的区别
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
其实两者比较好理解,通常created使用的次数多,而mounted通常是在一些插件的使用或者组件的使用中进行操作,比如插件chart.js的使用: var ctx = document.getElementById(ID);通常会有这一步,而如果你写入组件中,你会发现在created中无法对chart进行一些初始化配置,一定要等这个html渲染完后才可以进行,那么mounted就是不二之选。下面看一个例子(用组件)。

    Vue.component("demo1",{
            data:function(){
                return {
                    name:"",
                    age:"",
                    city:""
                }
            },
            template:"<ul><li id='name'>{{name}}</li><li>{{age}}</li><li>{{city}}</li></ul>",
            created:function(){
                this.name="唐浩益"
                this.age = "12"
                this.city ="杭州"
                var x = document.getElementById("name")//第一个命令台错误
                console.log(x.innerHTML);
            },
            mounted:function(){
                var x = document.getElementById("name")//第二个命令台输出的结果
                console.log(x.innerHTML);
            }
        });
        var vm = new Vue({
            el:"#example1"
    })
    

输出如下:
在这里插入图片描述
可以看到都在created赋予初始值的情况下成功渲染出来了。
但是同时看console台如下:
在这里插入图片描述
可以看到第一个报了错,实际是因为找不到id,getElementById(ID) 并没有找到元素,原因如下:
在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素
而在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点,故输出了结果“唐浩益”。
14. :key的作用

  1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。

  2. 同一层级的一组节点,他们可以通过唯一的id进行区分。

当页面的数据发生变化时,Diff算法只会比较同一层级的节点:

如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。

如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。
 当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。
 如下:

在这里插入图片描述
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:

在这里插入图片描述
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?

所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

在这里插入图片描述
所以一句话,key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,

否则vue只会替换其内部属性而不会触发过渡效果。

15.IE67下display:inline-block不起作用的解决办法
有两种方法:
1、先使用 display:inline-block 属性触发块元素,然后再定义 display:inline,让块元素呈递为内联对象(两个display 要先后放在两个 CSS 声明中才有效果,这是 IE 的一个经典 bug ,如果先定义了 display:inline-block,然后再将 display 设回 inline 或 block,layout 不会消失)。代码如下(…为省略的其他属性内容):

    div {display:inline-block;...}
    div {display:inline;}

2、直接让块元素设置为内联对象呈递(设置属性 display:inline),然后触发块元素的 layout(如:zoom:1 等)。代码如下:

div {display:inline; zoom:1;...}

16,清除浮动的几种方式

1、父级div定义伪类:after和zoom
IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
目前最好用的一种方法。

<style type="text/css"> 
   .div1{background:#000080;border:1px solid red;}
   .div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
   
   .left{float:left;width:20%;height:200px;background:#DDD}
   .right{float:right;width:30%;height:80px;background:#DDD}
   
   /*清除浮动代码*/
   .clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
   .clearfloat{zoom:1}
   </style> 
<div class="div1 clearfloat"> 
<div class="left">Left</div> 
<div class="right">Right</div> 
</div>
<div class="div2">
   div2
   </div>

2.在结尾处添加空div标签clear:both
以前最主要的清除浮动方法


<style type="text/css"> 
   .div1{background:#000080;border:1px solid red}
   .div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
   
   .left{float:left;width:20%;height:200px;background:#DDD}
   .right{float:right;width:30%;height:80px;background:#DDD}
   
   /*清除浮动代码*/
   .clearfloat{clear:both}
   </style> 
<div class="div1"> 
<div class="left">Left</div> 
<div class="right">Right</div>
<div class="clearfloat"></div>
</div>
<div class="div2">
   div2
   </div>

二、JS部分

1.请 分别用文字与代码描述闭包

1.可以读取到其他函数内部的变量
2.可以将变量保存在内存中
让我们说的更透彻一些。所谓“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量。这使得只要目标 对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目 标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新 的值,和上次那次调用的是各自独立的。


function a() {
	 var i = 0; 
	 function b() { 
	 	alert(++i); 
	 	} return b; 
} 
var c = a(); 
c();

2.请列出函数有哪些不同的调用方式

javascript 函数有4种调用方式
每种方式的不同方式在于this 的初始化

this 关键字
this 指向函数执行时的当前对象,this 是保留关键字,不能修改this 的值

全局对象
当函数没有被自身的对象调用时,this 的值就会变成全局对象
web 浏览器全局对象 window对象

调用方法
一、作为一个函数调用

function myFn(a, b) {
    return a + b;
}
myFn(10, 2);

二、函数作为方法调用

  var myObject = {
        firstName: "huang",
        lastName: "weisheng",
        fullName: function() {
            return this.firstName + this.lastName;
        }
    }

myObject.fullName();

三、使用构造函数调用
如果函数调用前使用了new 关键字,则是调用了构造函数
js函数重新创建的对象,而不是创建新的函数
构造函数中this 关键字没有任何的值
this 的值在函数调用时实例化对象(new object)时创建

function myFn(arg1, arg2){
    this.firstName = arg1;
    this.lastName = arg2;
}
var x = new myFn("huang", "weisheng");
x.firstName;

四、作为函数方法调用
在js 中,函数是对象,也有方法和属性
call() 和apply() 是预定义的函数方法,可用于函数调用,第一个参数为对象本身
call() 第二个参数开始为call 的参数

function myFn(a, b) {
    return a + b;
}
myObject = myFn.call(myObject, 10, 2);


apply() 第二个参数为数组
function myFn(a, b) {
    return a + b;
}
myArray = [10, 2];
myObject = myFn.apply(myObject, myArray);

3.请使用文字或代码简述$.each()的实现

$(function () { 
	$.each([52, 97], function(index, value) {
  		alert(index + ': ' + value);
});
})

//0:52
//1:97

4.运行下面代码输出的值是什么?


var length=10;
function fn(){
	console.log(this.length);
}
var obj={
	length:5,
	method:function(fn){
		fn();
		arguments[0]();
	}
};
obj.method(fn,1);

//结果为10   2
//arguments[0]() => fn() =>this指向arguments所以输出arguments.length
/*
第一个 fn  this指向window   输出10
第二个 arguments[0]() 可以理解为arguments.0() [只是方便理解] ,
            即argument对象调用fn函数,所以this指向arguments对象
arguments = {
  0:fn,    //function fn(){console.log(this.length);}
  1:第二个参数 1,
  length:2
}
*/


5.判断下面字符串中出现次数最多的字符,并统计次数

var str='aaabbbcccaaabbbaaa';
var o={};
for(var i=0;i<str.length;i++){
	var char=str.charAt(i);   //charAt() 方法可返回指定位置的字符。
	if(o[char]){
		o[char]++;
	}else{
		o[char]=1;
	}
}
console.log(o)      //{a: 9, b: 6, c: 3}
var max=0;
for(var key in o){
	if(max<o[key]){
		max=o[key];
	}
}
for(var key in o){
	if(o[key]==max){
		console.log("最多的字符是"+key);
		console.log("出现的次数是"+max);
	}
}
//最多的字符是a;
//出现的次数是9;

6.获取url中的参数
url:https://mp.csdn.net/mdeditor/89814963?k1=1&k2=2&k3=3


//获取URL参数生成json
			function GetRequest() {
				var url = location.search; //获取url中"?"符后的字串   
				var theRequest = new Object();
				if(url.indexOf("?") != -1) {
					var str = url.substr(1);
					strs = str.split("&");
					for(var i = 0; i < strs.length; i++) {
						theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
					}
				}
				return theRequest;
			}
var urlparam={};
urlparam = GetRequest();
var k1 = urlparam.k1;
var k2= urlparam.k2;
var k3= urlparam.k3;
console.log("k1="+k1);  //k1=1
console.log("k2="+k2);  //k2=2
console.log("k3="+k3);  //k3=3

7.判断下列函数得输出结果

var bar=true;
			if(bar===true){
				var a=1;
			}
			function bs(){
				var b=2;
				 c=3;
			}
			console.log(a); //1
			console.log(b); //undefined;
			console.log(c); //undefined;

8.判断下列函数得输出结果

		console.log("34343");
		setTimeout(function(){ //异步
			console.log(111);
		},0)
		new Promise(function(resolve){
			console.log("222332");
			resolve();
		}).then(function(){
			console.log("promise");
		})	
		console.log("4444");

//34343
//222332
//4444
//promise
//111

以上是我总结的部分面试题后续会继续更新,如有问题,请留言指正共同学习,谢谢

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值