前端面试题

进程和线程的区别?

1.对操做系统来讲,一个任务就是一个进程,如打开一个浏览器、记事本;线程存在在进程内部。javascript

2.同一个进程能够包括多个线程,而且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程)php

死锁是什么?产生的缘由?必要条件?怎么处理?

1.相互等待资源所产生的一种僵持状态,若是没有外力干预将一直保持这个状态。css

2.系统资源不足、相互争抢资源、资源请求顺序不当html

3.互斥、不可抢占、循环等待、请求与保持前端

4.互斥是不可改变的,因此只能破坏其余三个条件中的一个来解除死锁,方法:剥夺资源、杀死其中一个线程html5

什么是HTML语义化?

根据内容使代码结构化,选择合适的标签能使代码语义化,便于开发者阅读和写出更优雅的代码,同时也让浏览器的爬虫和机器更好地解析java

为何要语义化?

  • 为了在没有CSS的状况下也能呈现出很好的内容结构es6

  • 用户体验更好,如title解释名词信息,alt解释图片信息ajax

  • 有利于SEO(search engine optimization):和搜索引擎创建良好的沟通,有利于爬虫抓取更多信息:爬虫依赖标签来肯定上下文和各个关键字的权重json

  • 方便其余设备解析(屏幕阅读器、盲人阅读器、移动设备)

  • 便于团队开发维护

写代码时要注意什么?

  • 尽量减小无语义标签的使用,如div和span

  • 语义不明显时,若是能够用div或p,尽可能用p,它默认有上下间距,对兼容特殊终端有利

  • 不要用纯样式标签,如b,font,u等

  • 须要强调的文本,能够包含在strong(加粗)或者em(斜体)中

  • 使用表格时,标题用caption,表头用thead,主体部分用tbody包围,尾部用tfoot包围。表头和通常单元格要区分开,表头用th,单元格用td

  • 表单域要用fieldset标签包起来,并用legend标签说明表单的用途

  • 每一个input标签对应的文本都用label标签,并经过为input设置id属性,在label中设置for=someid让说明文本和对应的input关联起来

HTML5新增的语义标签

header

footer

hgroup

nav

aside

section

article

行内元素有哪些?

a b(粗体) span img input strong select label em button textarea

块级元素有哪些?

div ul li dl(定义列表) dt(列表中的项目) dd(描述列表中的项目) p h1-h6 blockquote

空元素有哪些?

br meta hr(水平线分隔) link input img

inline、block、inline-block的区别?

inline:和其余元素都在一行上,高、行高及顶和底边距不可变,宽度就是其文字或图片的宽度,不可改变

block:总在新行上开始,高度,行高,及顶和底边距均可变,宽度缺省是它容器的100%,除非设定一个宽度

inline-block:将对象呈现为内联对象,可是对象的内容做为块对象呈现,块对象在一行内呈现,容许空格,能够设置块元素宽度和高度

inline和inline-block之间产生空隙的缘由

由于标签段之间的空格

移除空格的方法

  1. 去掉HTML中的空格

  2. 使用margin负值,这个负值的大小与上下文的字体和文字大小相关,大约在3-4像素之间

  3. 只在最后一个a标签后加上</a>(兼容IE),在HTML5直接不加结束标签

  4. 使用font-size:0

  5. 使用letter-spacing(字符间距)、word-spacing(单词间距)

     

position的取值

static:默认值,对象遵循常规流

relative:对象遵循常规流,并参照自身在常规流中经过top、right、bottom、left这4个定位偏移属性进行偏移时不会影响常规流中的任何元素

absolute:对象脱离常规流,此时偏移属性参照的是离自身最近的定位祖先元素,若是没有定位的祖先元素,则一直回溯到body元素。盒子的偏移位置不影响常规流中的任何元素,其中margin不与其余任何margin折叠

fixed:与absolute一致,但偏移定位是以窗口为参考。当出现滚动条时,对象不会随着滚动

center:与absolute一致,但偏移定位是以定位祖先元素的中心点为参考,盒子在其包含容器内水平居中(CSS3)

清除浮动的方法?

1.父级div定义height

  • 原理:父级div手动定义height,解决了父级div没法自动取得高度的问题

  • 优势:简单,代码少

  • 缺点:只适合高度固定的布局,要给出精确的高度

2.在结尾加一个空div标签,style="clear:both"

  • 原理:添加一个空div,利用css的clear:both清除浮动,让父级div能自动获取高度

  • 优势:简单,代码少,浏览器支持好

  • 缺点:若是页面浮动布局过多,就要增长不少空div,不建议使用

3.父级div定义,伪类:after和zoom(IE专有属性,解决IE6,7浮动问题)

father:after{display:block;clear:both;content:"";visibility:hidden;height:0}
father{zoom:1}
  • 优势:浏览器支持好

  • 缺点:代码多

4.父级div定义 overflow:hidden

  • 原理:必须定义width,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度

  • 优势:简单代码少,浏览器支持好

  • 缺点:不能和position配合使用,由于超出的尺寸会被隐藏

5.父级定义 overflow:auto

  • 原理同上

  • 优势:简单,浏览器支持好

  • 缺点:内部宽高超过父级div时,会出现滚动条

BFC

定义:(Block formatting context)块级格式化上下文,是一个独立的渲染区域,只有Block-level box参与,它规定了内部的Block-level Box如何布局,而且与这个区域外部绝不相干

BFC布局规则

  • 内部的Box会在垂直方向,一个接一个地放置

  • box垂直方向的距离有margin决定。属于同一个BFC的两个相邻的box的margin会发生重叠

  • 每一个元素的margin box的左边,与包含快border box的左边相接触,即便存在浮动也是如此

  • BFC的区域不会与float box重叠

  • BFC就是一个独立的隔离的容器,容器里面的子元素不会影响到外面的元素,反之也如此

  • 计算BFC高度时,浮动元素也参与运算

哪些元素会产生BFC

  • 根元素

  • float属性不为none

  • position为absolute或者fixed

  • display属性为inline-block、table-cell、table-caption、flex、inline-flex

  • overflow不为visible

盒模型

盒模型分为IE盒模型和W3C标准盒模型

1.W3C盒模型:width,height只包含content,不包含border和padding

2.IE盒模型:width,height包含border和padding,指的是content+padding+border

在IE8+的浏览器中能够设置box-sizing控制,默认值为content-box,若是设为border-box则用的是IE盒模型

Transform/transition/animation

transform:一个静态属性,一旦写到style里面会直接显示做用,无任何变化过程

transform/animation:这两个属性实现的功能都是同样的,经过控制属性变化的过程,实现动画,都是立足于控制自己dom和css属性变化过程,来实现动画的视觉效果;区别在于,二者的控制力度不同,transition更加粗糙一点,对过渡的速度进行了封装,能够控制是匀速改变仍是贝塞尔曲线等,而animation指定的keyframe方法,能够手动去指定每一个阶段的属性,此外还有循环次数、动画延迟等功能,更加自由强大

padding/margin使用百分比单位

这种状况下都是根据最近的父级容器的宽度width进行计算的

使用百分比单位的目的:弥补元素高度没法自适应地与元素宽度保持一致的缺陷

css元素权重

  1. 内联样式表的权值最高 1000。

  2. ID 选择器的权值为 100。

  3. Class 类选择器的权值为 10。

  4. HTML 标签(类型)选择器的权值为 1。

  5. 属性选择器的权重为10

  6. 通配符权重为0

  7. 伪类选择器权重为10

  8. 伪元素选择器权重为1

 

JavaScript数据类型

一共7种:字符串、数字、布尔值、数组、对象、Null、Undefined

this的指向问题

this:在执行上下文建立时肯定的一个在执行过程当中不可更改的变量

this只在函数调用阶段肯定,也就是执行上下文建立的阶段进行赋值,保存在变量对象中,因此也致使了this的多变性,函数在不一样的调用方式下均可能致使this的值不一样

可是this的指向在严格模式下和非严格模式下有所不一样。当函数独立调用时,严格模式下this指向undefined,非严格模式下,当this指向undefined时,自动指向全局对象(浏览器中就是window)

当一个对象在全局声明时,对象内部属性中的this指向全局对象,当对象在一个函数中声明时,严格模式下this会指向undefined,非严格模式下转为指向全局对象

函数的调用方式

  • 在全局环境或是普通函数中直接调用

 1 var a = 1;
 2 var obj = {
 3     a:2,
 4     b:function (){
 5         function fun(){
 6             return this.a
 7         }
 8         console.log(fun());
 9     }
10 }
11 obj.b();//1

 

 

  • 做为对象的方法

1 var a = 1;
2 var obj = {
3     a:2,
4     b:function() {
5         return this.a
6     }
7 }
8 console.log(obj.b())//2

 

b所引用的匿名函数做为obj的一个方法调用,这时候this指向调用它的对象,这里也就是obj

那么不做为对象的方法调用是什么意思呢?

1 var a = 1;
2 var obj = {
3     a:2,
4     b:function(){
5         return this.a;
6     }
7 }
8 var t = obj.b;
9 console.log(t());//1

 

这里的t应该理解为指向b属性的指针

  • 使用apply或者call

  • 做为构造函数

构造函数:经过new关键字批量生产咱们须要的对象的函数,如FUNCTION、object、Array、Date等全局定义的构造函数,注意,构造函数首字母要大写

 1 function Category(){
 2     this.name = 'annika';
 3     this.school = 'college';
 4     this.height = '160';
 5     this.run = function(){
 6         return this.name + '正在跑步';
 7     }
 8 }
 9 Fun.prototype = {
10     constructor:Fun,
11     say: function(){
12         return this.name + '正在说话';
13     }
14 }
15 var f = new Fun();
16 f.run();  //annika正在跑步
17 f.say();  //annika正在说话

 

若是函数做为构造函数用,那么其中的this就表明它即将new出来的对象

new作了以下的事

  • 建立一个临时对象

  • 给临时对象绑定原型

  • 给临时对象对应的属性复制

  • 将临时对象返回

箭头函数

箭头函数不能够用call和apply改变this

 1 var a = 1;
 2 var obj = {
 3     a:2
 4 };
 5 var fun = () => console.log(this.a);
 6 fun(); //1
 7 fun.call(obj); //1
 8 var a = 1;
 9 var obj={
10     a:2
11 };
12 function fun(){
13     var a = 3;
14     let f = () => console.log(this.a);
15     fun();
16 }
17 fun();//1
18 fun.call(obj);//2

 

注意,此时fun的上下文就是箭头函数所在的上下文,所以此时的f的this为fun的this,也就是window,当fun.call(obj)再次调用时,新的上下文被建立,fun此时的this为obj,也就是箭头函数的this值

1 function Fun(){
2     this.name = 'annika';
3 }
4 Fun.prototype.say = () => {
5     console.log(this);
6 }
7 var f = new Fun();
8 f.say(); //window

 

此时箭头函数所在的上下文是__proto__所在的上下文也就是Object函数的上下文,而object的this值就是全局对象

1 function Fun(){
2     this.name = 'annika'
3     this.say = () => {
4         console.log(this);
5     }
6 }
7 var f = new Fun();
8 f.say(); //Fun的实例对象

 

此时箭头函数所在的上下文变成了Fun的上下文环境,由于当函数做为构造函数调用的时候,上下文环境的this指向实例对象

做用域和做用域链

变量的做用域分为两种:全局变量和局部变量

全局做用域:最外层定义的变量拥有全局做用域,对于其内部函数来讲,都是能够访问的

局部做用域:通常只在固定的代码片断内能够访问到,对于函数外部是没法访问的,最多见的例如函数内部

做用域链:内部函数能够访问外部函数变量的机制,用链式查找决定哪些数据能被内部函数访问。

执行环境(execution context):每一个函数运行时都会产生一个执行环境js为每个执行环境关联了一个变量对象。环境中定义的全部变量和函数都保存在这个对象中。

全局执行环是最外围的执行环境,被认为是window对象,所以全部的全局变量和函数都是做为window的属性和方法建立的。

js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中,而在函数执行以后,栈将该函数的变量对象弹出,把控制权交给以前的执行环境变量对象

当某个函数第一次被调用时,就会建立一个执行环境,及相应的做用域链,并把做用域链赋值给一个特殊的内部属性[scope]。而后用this,arguments和其余的命名参数的值来初始化函数的活动对象。当前执行环境的变量对象始终在做用域链的第0位。

标识符解析是沿着做用域链一级一级地搜索标识符的过程。搜索过程始终从做用域链的前端开始,而后逐级向后回溯,直到找到标识符为止

闭包

定义:一种内部函数的做用域链依然保持着对父函数活动对象的引用的函数

做用:

  • 能够读取自身函数外部的变量(沿着做用域链查找)

  • 可让这些外部变量始终保存在内存之中

缺点:

1.因为闭包会使得函数中的变量都保存在内存中,内存消耗很大,因此不能滥用闭包,不然会形成网页的性能问题,在IE中可能致使内存泄漏,解决方法是,在退出函数以前,将不使用的局部变脸所有删除

2.闭包会在父函数外部,改变父函数内部变量的值。

原型与原型链

函数的原型对象:在js中,咱们在声明一个函数的时候,浏览器的内存中会建立一个对象B,并且并且每一个函数都默认会有一个属性prototype指向了这个对象,这个B就是函数A的原型对象,简称函数的原型。这个原型对象B默认会有一个属性constructor指向这个函数A。原型对象默认只有属性:constructor。其余都是从Object继承而来

使用构造函数建立对象:把一个函数做为构造函数,使用new建立对象的时候,那么这个对象就会存在一个默认的不可见的属性,来指向了构造函数的原型对象。这个不可见的属性通常用[[prototype]]来表示,只是这个属性没有办法直接访问到

与原型有关的几个属性和方法

1.constructor属性:存在于原型对象中,它指向构造函数。咱们有时候能够根据prototype属性,来修改原来的原型对象,可是通过修改,原型对象会失去对原来的constructor的指针,此时能够手动再绑定回去

2.__proto__属性:个别浏览器提供了对[[prototype]]的访问方法,就是这个属性,这个是对象的属性,可是尽可能不要用这种方法访问,他有可能改变这个对象的继承原型链

3.hasOwnProperty()方法

用来判断一个属性是来自对象自己,仍是来源于其所在的原型链。注意只能判断是否是来自对象,不能判断原型中存不存在,由于无论存不存在都会返回false

4.in操做符

用来判断一个属性是否存在于这个对象中。可是在查找这个属性的时候,先在对象自身中找,若是对象找不到,再到原型中去找。只要对象和原型中有一个地方存在这个属性,就返回true

原型建立对象的缺陷:由于原型中的全部属性都是共享的,因此若是对一个对象的原型的属性作了修改,会反应到全部的对象上面。这个共享的形式对属性值是函数的属性很方便

构造函数模型建立对象的缺陷:构造函数中的全部属性和方法,每一个对象独有,不会共享,可是对方法又不太合适,由于有时只须要一个方法

组合模式解决缺陷:基于以上两台产生了组合模式,原型模式适合封装方法,构造函数模式适合封装属性,综合两种模式的优势就有了组合模式

动态原型模式建立对象:组合模式有一点不完美,就是把构造方法和原型分开写,让人感受不舒服,因此应该想办法把构造方法和原型封装在一块儿,因此有了动态原型模式。动态原型模式把全部的属性和方法都封装在构造方法中,仅在须要的时候才去构造方法中初始化原型,又保持了原型和构造函数的优势。

 1 function(name,age){
 2     this.name = name;
 3     this.age = age;
 4     if(typeof this.eat !== "function"){
 5         Person.prototype.eat = function(){
 6             return(this.name + 'eating')
 7         }
 8     }
 9 }
10 var p1 = new Person('annika',21);
11 p1.eat();

 

宏任务与微任务

  • 宏任务按顺序执行,且浏览器在每一个宏任务之间渲染页面

  • 全部的微任务也按顺序执行,且在如下场景会当即执行全部微任务

    • 每一个回调以后,且js执行栈中为空

    • 每一个宏任务结束以后

跨域问题

  • 为何会出现跨域问题

    • 处于浏览器的同源策略限制,浏览器会拒绝跨域请求,但不是全部的跨域都会被拒绝,有以下三种状况:

      • 一般浏览器容许跨域写操做(cross-site writes),如连接、重定向

      • 一般容许跨域资源嵌入(cross-site embedding),如img,script

      • 一般浏览器不容许跨域读操做(cross-site reads)

  • 什么状况算做跨域

    • 非同源请求,同源——两个页面拥有相同的协议(protocol),端口(port)和主机(host),那么这两个页面就属于同一个源(origin)

  • 为何有跨域需求

    • 工程服务化之后,不一样职责额服务分散在不一样的工程中,每每这些工程的域名是不一样的,一个需求可能对应多个服务,这是就须要使用不一样的服务接口,所以会出现跨域

  • 如何实现跨域

    • 最经常使用的跨域方式有三种:JSONP、CORS、postMessage

    • JSONP

      • 实现原理:虽然不能经过XHR请求不一样域上的数据,可是在页面上引入不一样域的js脚本是能够的,在js文件载入完毕后,触发回调,能够将须要的data做为参数传入

      • 实现方式(需先后端配合)

         1 <script type="text/javascript">
         2     function dosomething(data){
         3         //处理得到的数据
         4     }
         5 </script>
         6 <script src="http://example.com/data.php?callback=dosomething"></script>
         7 <?php
         8 $callback = $_GET['callback'];//获得回调函数名
         9 $data = array('a','b','c');//要返回的数据
        10 echo $callback.'('.json_encode($data).')';//输出
        11 ?>

         

      • 优缺点

        优势:兼容性好

        缺点:1.JSONP只支持GET请求;2.XMLHTTPRequest相对于JSONP有更好地错误处理机制

    • CORS(cross-origin resource sharing )跨域源资源共享

      • 基本思想:使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功仍是失败。

      • IE实现

        1 var xdr = new XDomainRequest();
        2 xdr.onload = function(){
        3     alert(xdr.responseText);
        4 }
        5 xdr.open("get","http://www.somewhere-else.com/page/");
        6 xdr.send(null);

         

      • 其余浏览器:原生支持CORS

         1 var xhr = createXHR();
         2 xhr.onreadyStatechange = function(){
         3     if(xhr.readyState == 4){
         4         if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
         5             alert(xhr.responseText);
         6         } else{
         7             alert("Request was unsuccessful:" + xhr.status);
         8         }
         9     }
        10 };
        11 xhr.open("get","http://www.somewhere-else.com/page/",true);
        12 xhr.send(null);

         

    • postMessage

      • window.postMessage(message,targetOrigin)方法是html5新引进的特性,能够用它来向其余window对象发送信息,不管同源不一样源

        1 otherWindow.postMessage(message,targetOrigin,[transfer]);

         

         

前端攻击

  • XSS攻击

深拷贝和浅拷贝

  • 主要区别:在内存中的储存类型不一样

    栈是自动分配的内存空间,它由系统自动释放,而堆是动态分配的内存,大小不定,也不会自动释放

  • 基本数据类型(boolean/number/string/undefined/null)存放在栈中,是直接按值存放的,能够直接访问,且基本数据类型的值不可变,基本类型的比较是值得比较,只要值相等就认为其相等

  • 引用类型(object)存放在堆中,变量其实是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每一个空间大小不同,要根据状况进行特定的分配。引用类型的值可变,引用类型的比较是引用的比较,看其引用是否指向同一个对象

  • 传值与传址:基本数据类型的赋值是在内存中新开辟一段栈内存,而后再把值赋到新的栈中,因此两个变量相互独立不影响;引用类型的赋值是传址,只是改变指针的指向,也就是说引用类型的赋值是对象保存在栈中的地址的赋值,两个变量指向同一个对象,所以二者之间操做相互有影响

  • 浅拷贝只复制一层对象的属性,并不包括对象里面的为引用类型的数据。

  • 深拷贝是对对象及全部的子对象进行拷贝

ajax的过程

0:未初始化,还没有调用open方法

1:启动,已经调用open方法,但还没有调用send方法

2:发送,已经调用send方法,可是还没有收到响应

3:接收,已经收到部分响应数据

4:完成,已经接收到所有响应数据,能够在客户端使用了

 1 //建立XMLHttpRequest对象
 2 var xmlhttp = null;
 3 if(window.XMLHttpRequest)
 4 {
 5     xmlhttp = new XMLHttpRequest();
 6 }
 7 else if(window.ActiveXObject)
 8 {
 9     xmlhttp = new ActiveXobject("Microsoft.XMLHTTP");
10 }
11 12 if(xmlhttp != null)
13 {
14     //指定响应函数
15     xmlhttp.onreadyStatechange=State_change;
16     //打开链接(指定请求)
17     xmlhttp.open("GET","/example/note.xml",true);
18     //发送请求
19     xmlhttp.send(null)
20 }
21 22 //建立响应函数
23 function State_change()
24 {
25     if(xmlhttp.readyState == 4)
26     {
27         if(xmlhttp.status == 200)
28         {
29             //具体逻辑
30         }
31     }
32     else
33     {
34         alert("error");
35     }
36 }

 

es6新特性

  • let和const

  • 变量的解构赋值

  • 箭头函数

  • Set和Map结构

  • Iterator和for..of循环

  • Generator函数

  • promise对象

    • 三个状态(resolve/reject/pending)

    • async函数

      • Genarator函数的语法糖

      • 优势在于内置执行器,拥有更好地语义和更广的适用性

  • class

事件捕获和事件冒泡

事件冒泡:先触发子元素的处理器,再触发父元素的事件处理器,每向上走一层都会检查这一层有没有事件处理器,若是有就触发,若是没有就继续向上查找,直到顶层body

事件捕获:从body向下找,若是父级元素有事件处理器就先触发父级元素,再向下一层,直到这个点击位置的最底层,也就是target

DOM2级事件流总共分为三个阶段:事件捕获、在目标元素上、事件冒泡

两个方法:addEventListener()和removeEventListener(),接受三个参数:事件名称、事件处理器,和布尔值,布尔值默认为false,表明事件处理器在冒泡阶段触发,true表明在捕获阶段触发

Dom0级事件只能在冒泡阶段触发

若是要一次性注册多个事件:

  • 对于非target节点先执行捕获再执行冒泡

  • 对于target节点先执行先注册事件

处理事件代理时,event有两个特殊属性,event.target和event.currentTargret,前者是事件触发元素,后者是事件绑定元素,大部分状况下,在使用事件代理时,event.target是子元素,event.currentTarget是父元素

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息