前端面试题

面试题

一.HTML

1.常用哪些浏览器进行测试,对应有哪些内核?

①IE------------------->Trident

②Chrome---------->以前是Webkit现在是Blink

③Firefox------------>Gecko

④Safari-------------->Webkit

⑤Opera-------------->最初是Presto,后来是Webkit,现在是Blink(Webkit的分支)

2.行内元素和块级元素的区别?行内块元素的兼容性使用?(IE8以下)

①行内元素:会在水平方向排列,不能包含块级元素。设置width无效,height无效(可以设置line-height),margin无效,padding上下无效

块级元素:各占一行,垂直方向排列。

②display:inline-block;*display:inline;*zoom:1;
*zoom:1作用是
在IE下触发hasLayout
*display:inline作用作用是
一旦触发了hasLayout设置display:inline和display:block效果相似。

3.清除浮动的方法有哪些,哪个比较好

父级div增加height,一般不用

浮动div标签加空div元素clear:both;

父级div加伪类元素after和zoom-------------------最好用,大多数网站都用

父级div定义overflow:hidden。
父级div定义overflow:auto。

4.box-sizing有哪些属性,分别什么作用?

①content-box:不包含border和padding

②border-box:包含border和padding

5.Doctype作用?标准模式和兼容模式各有什么区别?

<!Doctype>位于 HTML文件的第一行,是在html标签之前。他告诉浏览器的解析器用什么标准文档来解析这个文档。如果<!Doctype>不存在或者格式不正确的就会导致文档以兼容性模式存在。

②标准模式的排版和JS运作的最高模式都是以浏览器支持的最高标准运行。在兼容模式中,总是以宽松的向后兼容的方式显示,模拟老浏览器的行为以防止站点无法工作。

6.HTML5为什么只需要 <!DOCTYPE HTML>?

①HTML5不是基于SGML因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照他们应该的方式来运行)

②HTML4.01是基于SGML,所以需要对DTD进行引用,这样才能告知浏览器文档所使用的文档类型。

7.页面引入样式时,使用link与@import有什么区别?

①link是XHTML标签,除了加载CSS外还可以用于定义RSS,定义Ref连接属性等作用。而@import是CSS所提供的只能用于加载CSS

②link引入CSS时是在页面载入的同时加载的,而@import是页面网页完全载入之后加载的

③link是XHTML标签没有兼容问题,@import是CSS2.1提供的,低版本(ES5以下)的浏览器不支持

④link支持使用javascript控制DOM去改变样式,而@import不支持

8.介绍一下你对浏览器内核的理解

主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。

浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎:解析和执行javascript来实现网页的动态效果。

最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。

9.html5有哪些新特性?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

①HTML5 现在已经不是 SGML 的子集,主要是关于图像画布,音频视频,存储,语义化标签,表单控件,多任务,位置等功能的增加。
(1)绘画 canvas;
(2)用于媒介回放的 video 和 audio 元素;
(3)本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
(4)sessionStorage 的数据在浏览器关闭后自动删除;
(5)语意化更好的内容元素,比如 article、footer、header、nav、section;
(6)表单控件,calendar、date、time、email、url、search;
(7)新的技术webworker, websocket, Geolocation;
②IE6/IE7/IE8支持通过document.createElement方法产生的标签,
可以利用这一特性让这些浏览器支持HTML5新标签,
浏览器支持新标签后,还需要添加标签默认的样式。
当然也可以直接使用成熟的框架、比如html5 shim;
< !--[if lt IE 9]> < script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script> < ![endif]-->

10.简述一下你对HTML语义化的理解?

①表示:用正确的标签做正确的事情。
②好处:

1.页面结构化,使阅读网站源代码的人能够快速理清HTML文档的结构,便于学习和后期维护。

2.即使在没有样式的情况下也以一种文档的格式在用户面前展示,用户容易理解阅读;
3.有利于SEO,因为搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重

二.VUE

1、事件委托

①子级的事件委托给父级来处理

② 比如一个宿舍的同学同时快递到了,一种方法就是他们一个个去领取,还有一种方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一 一分发给每个宿舍同学

③优点 : 可以大量节省内存占用,减少事件注册

​ 可以实现当新增子对象时无需再次对其绑定(动态绑定事件)

2、深拷贝,浅拷贝,实现深拷贝的几个方法

2.1 类型

值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null

**引用类型:**对象(Object)、数组(Array)、函数(Function)

2.2 浅拷贝与深拷贝

浅拷贝:只是增加了一个指针指向已存在的内存地址

方法1:Object.assign()

浅拷贝,只能拷贝一层,如果想全部拷贝,必须深层次的进行拷贝

eg:

let obj1={name:'张三',action:{say:'hi'}};
let obj2=Object.assign({},obj1);//把obj1复制给{}中
obj2.name='李四'
obj2.action.say='hello'
console.log('obj1',obj1)
//obj1 {name:'张三',action:{say:'hello'}}
console.log('obj2',obj2)
//obj2 {name:'李四',action:{say:'hello'}}

方法2:展开运算符...

展开运算符是es6的一个特性,他提供了一种非常方便的方式来执行浅拷贝,这与Object.assign()功能相同

let obj1={name:'张三',action:{say:'hi'}}
let obj2={...obj1}
obj2.name='李四'
obj2.action.say='hello'
console.log('obj1',obj1)
//obj1 {name:'张三',action:{say:'hello'}}
console.log('obj2',obj2)
//obj2 {name:'李四',action:{say:'hello'}}

***注意:concat(),slice()也属于浅拷贝

深拷贝:是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的地址

方法1:JSON.parse(JSON.stringify())

//深拷贝
let obj1={name:'张三',action:{say:'hi'}}
let obj2=JSON.parse(JSON.stringify(obj1))
obj2.name='李四'
obj2.action.say='hello'
console.log('obj1',obj1)
//obj1 {name:'张三',action:{say:'hi'}}
console.log('obj2',obj2)
//obj2 {name:'李四',action:{say:'hello'}}

方法2:jQuery.extend()

$.extend(deepCopy, target, object1, [objectN]) //第一个参数为true,就是深拷贝

//深拷贝
let obj1={name:'张三',action:{say:'hi'}}
let obj2=$.extend(true,{},obj1)
obj2.name='李四'
obj2.action.say='hello'
console.log('obj1',obj1)
//obj1   {name:'张三',action:{say:hi}}
console.log('obj2',obj2)
//obj2 {name:'李四',action:{name:'hello'}}

3、this指向

3.1.函数中

非箭头函数

如果一个标准函数,也就是非箭头函数,作为某个对象的方法被调用时,那么这个this指向的就是这个对象

   function print(){
            console.log(this)//obj
        }
        let obj={
            a:1,
            b:2
        }
    obj.print=print;
    obj.print();

如果某个函数是作为级联的对象对象用,那么函数的this指向级联里面的对象

   function print(){
            console.log(this)//obj.o-->print()函数并不是作为obj这个对象里的方法来调用,他是作为obj.o里面的对象来调用的
        }
        let obj={
            a:1,
            b:2,
            o:{}
        }
        obj.o.print=print;
        obj.o.print();

箭头函数

箭头函数的指向和定义这个箭头函数的上下文有关

  let print=()=>{
            console.log(this);//window--->全局window情况下
        }
        let obj={
            a:1,
            b:2
        }
   obj.print=print
   obj.print()

改变this指向方法

call()

apply()

bind()()

      function print(){
            console.log(this)//指向o
        }
        let obj={
            a:1,
            b:2
        }
        let o={
            c:3
        }
        obj.print=print
        // obj.print.call(o)
        // obj.print.bind(o)()
        obj.print.apply(o)
3.2 构造函数中

构造函数默认指向

       function Person(name){
              this.name=name;
              console.log(this)//person
        }
        // 构造函数new之后---new操作符实例化一个构造函数return默认就会有的
        let person=new Person('小汉')
        // new操作符实例化一个构造函数的情况下
        // 1.let o=new Object()
        // 2.this->o
        // 3.return o

构造函数–>改变构造函数的值

      function  Person(name){
            this.name=name
            console.log(this)
            // 如果return的是基本数据类型那么就不会改变实例化对象的值
            // return '123'   
            // 如果是非基本数字类型就会改变\
            // return new Date()
            return {}
        }
        let person =new Person('小汉')
        // 改变实例化对象
        console.log(person.name)//---undefined
3.3 闭包的情况下

**闭包:**两个或者两个以上的嵌套函数,其内部的函数在运行的时候就是一个闭包

闭包的情况下一般指向window

// "use strict"   严格模式下是undefined
    function print(){
        return function(){
            console.log(this)//非严格模式下是window   
        }
    }
    let obj={
        o:1
    }
    obj.print=print
    obj.print()()

并不是闭包函数一定指向的window

  // 并不是闭包函数一定指向的window
    function outer(){
        let obj={
            inner:function(){
                console.log(this)//this指向的是obj
            }
        }
        obj.inner()
    }
    let o={
        a:1,
        b:2
    }
    o.outer=outer
    o.outer()

4、定位居中的几种方法(垂直水平居中);

<body>
    <div class="big allCenter">
        <div class="small allCenterChild"></div>
    </div>
</body> 
<style>
.big{
       width: 100px;
       height: 100px;
       background-color: bisque;
     
   }
   .small{
       width: 50px;
       height: 50px;
       background-color: aqua;
   }
</style>
4.1 flex弹性布局:它的所有子元素自动成为容器成员

4.1.1 父级对子级进行垂直居中,居中属性只需要定义在父元素中

   .allCenter{
      display: flex; /* 设置弹性布局,display属性选为flex */
      justify-content: center;/*让子元素水平居中*/
      align-items: center;/*让子元素垂直居中*/
  }

4.1.2 让子元素用外边距自动顶开

  .allCenter{
      display: flex; /* 设置弹性布局,display属性选为flex */
  }
  .allCenterChild{
      margin: auto;/*等价于margin:auto auto auto auto;*/
  }

4.1.3

.allCenter{
      display: flex;/*设置弹性布局,display属性选为flex*/ 
  }
  .allCenterChild{
      align-self: center;/*脱离父级的align-items(垂直居中)属性,重写一遍,设置了垂直居中*/
      margin: 0 auto;/*设置水平居中*/
  }
4.2 Grid布局

4.2.1它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局

 .allCenter{
      display: grid;/*设置grid布局,display属性选为grid,定义在父级上面的属性*/  
  }
  .allCenterChild{
     justify-self: center;/*水平居中,横向*/
     align-self: center;/*垂直居中*/
  }
4.3用绝对定位

4.3.1子元素的上右下左距离都是一样的,上下左右都设置为0,【拔河效应】(元素宽高需要提前设定)

   .allCenter{
       position: relative;
   }
   .allCenterChild{
       position: absolute;
       left: 0;
       top: 0;
       right: 0;
       bottom: 0;/*这时候还没有垂直居中,仍然在左上角*/
       margin: auto;/*加上margin属性子元素才能垂直居中*/
   }

4.3.2绝对定位,子元素使用transfrom属性,【元素宽高无需设定】

 .allCenter{
       position: relative;
   }
  .allCenterChild{
       position:absolute;
	   top: 50%;
       left: 50%;
	   /*此时子元素的左上直角在父元素的中心点中,接下来需要把子元素的中心点移动到父元素的中心点位置中*/
       transform: translate(-50%,-50%);/*变形,子元素向左移动自身宽度的50%,向上移动自身高度的50%,向下向右移动则为正值*/
   }

4.3.3利用margin-top和margin-left【元素宽高需要设定】

   .allCenter{
    position: relative;
   }
   .allCenterChild{
       position:absolute;
	   top:50%;
	   margin-top:-25px;
	   left:50%;
	   margin-left:-25px;
   }
4.4 利用table的特征,只对表格有效

*在子元素没有设置宽高度和数量时使用
注意:table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height

 .allCenter{
       display: table-cell;/*设置为表格单元*/
       vertical-align: middle;/*设置表格属性,此时垂直居中了*/
       text-align: center;/*此时没有用,子元素此时为块元素,不是行内元素,text-align无效,需要对子元素进行处理称为行内块元素*/
   }
   .allCenterChild{
       display: inline-block;
   }
4.5 内容只有一行的时候可以用,其他的不可以使用,对文字进行水平垂直居中
<body>
    <div class="big allCenter">
        <div class="small allCenterChild">11111</div>
    </div>
</body>
<style>
   .big{
       width: 100px;
       height: 100px;
       background-color: bisque;  
   }
   .allCenter{
    font-size:25px;
    text-align: center;/*水平居中*/
	line-height:100px;/*行高跟父级的高度是一样的*/
   }
</style>

5、position有几种属性值以及区别

position具有四个属性:static(默认的)、absolute、relative、fixed

fixed:相对于浏览器窗口定位的、不会随滚动条的滚动而滚动

absolute:基于不为static的父元素进行定位,脱离了标准流

relative:基于自身定位,没有脱离标准流,仍然占据空间

static:没有定位,是默认值

6、git的一些使用和版本冲突的问题

6.1 git使用
6.1.1 新建分支

git clone 远端地址 拉取代码

git branch -a 查看本地分支与远程分支

git branch -r 查看远程分支

git branch 查看本地分支

git checkout -b 新分支 新建分支基于哪个分支下并且转到新分支

git log 查看当前分支记录

6.1.2 修改代码并合并

git add . 把工作时的所有变化提交到暂存区

git commit -m “提交说明” 要是将暂存区里的改动给提交到本地的版本库

git checkout develop 切换到主分支

git pull 拉取最新代码

git checkout 新分支 切换到新分支

git rebase develop 合并主分支

6.1.3 将代码推送到远程

*** 如果有冲突->修改文件之后提交

*git add .

*git commit -m “提交说明”

*git rebase --continue

git push origin 新分支 提交新分支

6.1.4 回退代码

(1) 回退到add 之前

git reset --soft HEAD^ 拉取服务器最近一次提交到暂存区,该操作不影响工作区

(2) 回退到指定版本

git reset --hard 目标版本号

git log 查看记录

6.1.5 添加暂存区

git stash save “save message” 添加到缓存区

git stash list 查看stash了哪些存储

git stash apply 应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{$num} , 比如第二个:git stash apply stash@{1}

git stash pop 命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}

git stash drop stash@{$num} 丢弃stash@{$num}存储,从列表中删除这个存储

git stash clear 删除所有缓存的stash

**注意:当在文件里面添加新的文件夹的时候git stash 不能追踪到 此时需要先添加到暂存区git add .

6.1.6 git revert和git reset的区别

原文https://blog.csdn.net/hudashi/article/details/7664460?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165158052016782246415098%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165158052016782246415098&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-6-7664460.142^v9^pc_search_result_cache,157^v4^control&utm_term=git+revert&spm=1018.2226.3001.4187

git revert 是生成一个新的提交来撤销某次提交,此次提交之前的commit都会被保留

git reset 是回到某次提交,提交及其之前的commit都会被保留,但是此次之后的修改都会被退回到暂存区

eg: 假设有三个commit

commit3: add test3.c

commit2: add test2.c

commit1: add test1.c

eg1 当执行git revert HEAD~1 commit2被撤销了

git log 可以看到

revert “commit2”:this reverts commit 5fe21s2…
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c

git status 没有任何变化

eg2 如果换做执行 git reset --soft(默认) HEAD~1后,运行git log

commit2: add test2.c

commit1: add test1.c

运行git status, 则test3.c处于暂存区,准备提交

eg3如果换做执行 git reset --hard HEAD~1后

显示:HEAD is now at commit2,运行git log

commit2: add test2.c

commit1: add test1.c

运行git status, 没有任何变化

***注意:git revert 是撤消该commit,作为一个新的commit。

7、cookie与session、token—未完成

8、事件的捕获和事件冒泡的流转过程是什么样子的

8.1 js事件流

一个完整的js事件流是从window开始,最后回到window的过程
在这里插入图片描述

*** 注意: 1-5是捕获过程,5-6是目标阶段,6-10是冒泡阶段;

8.2 代码示例
<body>
    <div onclick="console.log('我是div')" class="bigdiv">
        <button onclick="console.log('我是button')" class="bigbutton">
            <span onclick="console.log('我是span')">按钮</span>
        </button>
    </div> 
</body>
<style>
    .bigdiv{
        height: 300px;
        position: relative;
        background-color: bisque;
    }
    .bigbutton{
       position: absolute;
       width: 50px;
       height: 50px;
       left: 50%;
       top: 50%;
       transform: translate(-50%,-50%);
       background-color: aqua;
    }
</style>

详情图
在这里插入图片描述

8.3 addEventListener 方法

定义与方法

addEventListener()方法用于向指定元素添加事件句柄

***提示:使用removeEventListener()方法来移除addEventListener()方法添加的事件句柄

语法:

elment.addEventListener(event,function,useCapture)

参数值

event 必须。字符串,指定事件名。

***注意: 不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。

function 必须。指定要事件触发时执行的函数。

当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, “click” 事件属于 MouseEvent(鼠标事件) 对象。

useCapture 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。

可能值

true - 事件句柄在捕获阶段执行

false- false- 默认。事件句柄在冒泡阶段执行

8.4 如何阻止事件冒泡

(1) 在点击方法那里添加 .stop

  <div @click="outDiv" >
        //添加.stop阻止冒泡行为
        <div @click.stop="inDiv" >按钮</div>
   </div>

(2)阻止默认行为 .prevent

这样就不会跳转到链接地址了

<a href="https://baidu.com" @click.prevent="gobaidu">去百度</a>

如果后面再加上.once 那么只阻止一次,第二次还会跳转

<a href="https://baidu.com" @click.prevent.once="gobaidu">去百度</a>

阻止默认行为---->原生方法

<a href="https://baidu.com" @click="gobaidu">去百度</a>
gobaidu(event){
    //原生阻止默认行为
            event.preventDefault()
            console.log('去百度')
              }

9、display有哪些值?说明他们的作用?

display:none; 设置元素隐藏,具体可见:display:none
display:block; 设置元素为块级元素,块级元素可以独占一行,可设宽高。
display:inline; 设置元素为行内元素,一行可有多个行内块元素,可设宽高。
display:inline-block 设置元素为行内块元素,既有行内元素的(一行可有多个)特性,又有块元素的(可设宽高)特性
display:inline-table inline-table 得到的是,外面是“内联盒子”,里面是“table盒子”。
display:table 元素会作为块级表格来显示,类似 table,表格前后带有换行符;配合table-cell使用可实现水平垂直居中,具体可见:水平垂直居中
table-row 元素会作为一个表格行显示,类似 tr;
table-cell 元素会作为一个表格单元格显示,类似 td和 th。
display:list-item 为元素内容生成一个块型盒,随后再生成一个列表型的行内盒。

10、css选择器有哪些?优先级是什么样子的

10.1 元素与优先级:

1.在属性后面使用!important会覆盖页面内任何位置定义的元素样式

2.作为style属性写在元素内的样式

3.id选择器

4.类选择器

5.元素选择器

6.通配符选择器

7.浏览器自定义或继承

总结排序:!important>行内样式>ID选择器>类选择器>元素>通配符>继承>浏览器默认属性

10.2 补充解释

通配符选择器 也称为全局选择器,就是对所有的htmlz元素起作用。语法格式为: *{propery:value}。其中“*”表示对所有元素起作用,property表示css的属性,value表示属性值。

    

11.promise

11.1 应用场景:

异步操作

11.2 简单的promise用法:
    var promise=new Promise(function (resolve,reject){
            // 异步操作
            // 成功
            // resolve('成功')//执行.then
            // 失败
            reject('失败')//执行.catch
        })
        promise.then(function(value){
            console.log(value)
        }).catch(function(value){
            console.log(value);//失败
        })
11.3 链式应用
     var promise1=new Promise(function(resolve,reject){
          //   成功调用
          resolve('执行了promise1')
      })
      var promise2=new Promise(function(resolve,reject){
          resolve('执行了promise2')
      })
      var promise3=new Promise(function(resolve,reject){
          resolve('执行了promise3')
      })
      promise1.then(function(value){
          console.log(value)
          return promise2
      }).then(function(value){
          console.log(value)
          return promise3
      }).then(function(value){
          console.log(value)
      })
11.4 promise特有的两个方法

(1) all方法

等所有promise执行之后再返回结果

   var promise1=new Promise(function(resolve,reject){
        //  在promise中模拟异步操作
        setTimeout(()=>{
           console.log('promise1执行完成了')
           resolve('promise1执行')
        },1000)
    })
    var promise2=new Promise(function(resolve,reject){
        setTimeout(()=>{
            console.log('promise2执行完成了')
            resolve('promise2执行')
        },2000)
    })
    // 等所有promise执行之后再返回结果
    Promise.all([promise1,promise2]).then(function(value){
        console.log(value)
    }).catch(function(value){
        console.log(value)
    })

在这里插入图片描述

(2)race方法

   var promise1=new Promise(function(resolve,reject){
        //  在promise中模拟异步操作
        setTimeout(()=>{
           console.log('promise1执行完成了')
           resolve('promise1执行')
        },1000)
    })
    var promise2=new Promise(function(resolve,reject){
        setTimeout(()=>{
            console.log('promise2执行完成了')
            resolve('promise2执行')
        },2000)
    })
    // race->只要有一个完成,那么就结束了
    Promise.race([promise1,promise2]).then(function(value){
        console.log(value)
        console.log('race方法执行结束了')
    }).catch(function(value){
        console.log(value)
    })

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值