面试题
一.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)
})