面试题整理

265 阅读12分钟

一.  HTML

  • HTML5新增的标签和属性有哪些

1.form相关:
    form属性:表单元素可以放到表单外面,这时把form属性设置成表单id就行;
    formaction属性:给提交按钮(button,submit,imge)增加里这个属性,以便提交到不同服务器地址;
    formmethod属性:用法像formaction;
    placeholder属性:用于文本框未输入状态时的文本提示;
    autofocus属性:自动获得焦点,一个页面只能有一个空间有该属性;
    autocomeplete属性:自动完成浏览器对预测字段的输入,该属性的值有on/off/自定义
    list属性:用于单行文本框,该属性的值为某个datalist元素的id,增加完该属性后,功能类似与select,
              但是支持手输;但是考虑兼容性问题,我们通常设置datalist的css为none;
    <datalist>标签:定义可选的数据列表。与input文本框配合使用,可以做到输入值的下拉列表;
2.input元素类: 
    search:与文本框类似,用于搜索;
    tel:与文本框类似,用于电话;
    url:与文本框类似,用于url地址;
    email:用于email格式的地址;
3.增强的页面元素
    1.<figure>(图形)元素:figure是个组合元素,可以带标题<figcaption>,一个<figure>只允许放一个
      <figcation>标题;
    2.<detailes>(详情)元素:这个标签替代了将上面区域点击展开和收起的功能;<summary>点击元素,
      <p>展开内容;
    3.<mark>(标记)元素:页面需要突出显示或高亮的部分;
    4.<progress>(进度)元素:一般用于写进度条,可以给元素设置value和max属性;
    5.<meter>(公尺)元素:定义度量衡;
    6.<hearder>标签:
    7.<footer>标签:
    8.<small>标签:
    9.<audio>标签:声音
    10.<video>标签:视频
    11.<article>标签:定义外部的内容;
    12.<section>标签:定义w中的章节


二 .  CSS

  • 布局(例:两边宽度固定,中间自适应)

1.浮动的解决方案左侧元素与右侧元素优先渲染,分别向左和向右浮动中间元素在文档流的最后渲染,并将 width 设为 100%,则会自动插入到左右两列元素的中间,
随后设置 margin 左右边距分别为左右两列的宽度,将中间元素调整到正确的位置。这是一种比较便利的实现方式,无需额外的元素辅助定位,同时兼容性也比较优秀。
但有一个缺点就是该布局方式只能实现左右两列宽度固定,中间自适应这一种三列布局,灵活性不强。
核心代码:min-height: 100px;float: left;float: right;width: 300px;
2.绝对定位的解决方案
核心代码:min-height: 100px;position: absolute;left: 0;left: 300px;right: 300px;right: 0;

扩展:双飞翼布局 :结合float 和 position 和 BFC 

<div class="grid">  <div id="div-middle-02">  <div id="middle-wrap-02"><span>div-middle</span></div>
</div><div id="div-left-02"><span>div-left</span></div>
<div id="div-right-02"><span>div-right</span></div>
</div>
#div-middle-02 {
    float: left;
    background-color: #fff9ca;
    width: 100%;
    height: 50px;
}

#middle-wrap-02 {
    margin: 0 200px 0 150px;
}

#div-left-02 {
    float: left;
    position: relative;
    background-color: red;
    width: 150px;
    margin-left: -100%;
    height: 50px;

}

#div-right-02 {
    float: left;
    position: relative;
    background-color: yellow;
    width: 200px;
    margin-left: -200px;
    height: 50px;
}

3.flexbox的解决方案

设计一个弹性容器包裹需定位的三个元素,然后将该弹性容器的排列属性设为水平排列(flex-flow: row column)现在三个元素已经是三列布局了,再将三列元素分别设定一下宽度就行了,左右元素设定为定宽,自适应的中间
元素设定为 100%。
4.表格布局的解决方案
核心代码:min-height: 100px;display: table;display: table-cell;width: 300px;5.网格布局的解决方案

核心代码:display: grid;width: 100%;grid-template-rows: 100px;grid-template-columns: 300px auto 300px;

  • css3 新增属性

1.边框
    border-radius:圆角边框;
    border-shadow:边框阴影;
    border-image:边框图片;
2.背景
    background-size:规定背景图片的尺寸;
    background-origin:规定背景图片的定位区域;
3.文字效果
    text-shadow:文本阴影;
    word-warp:长单词分拆换到下一行
4.2D转换
    transform下的属性
    translate():left和top水平移动
    rotate()(旋转):旋转单位deg;
    scale()(比例):尺寸改变,x 和 y;
  • 超出文本显示省略号

.test{width:150px;overflow:hidden;white-space:nowrap;-o-text-overflow:ellipsis;
      text-overflow:ellipsis;}



三.   JavaScript

  • 对象继承的方式有哪些?

1、原型链继承

核心: 将父类的实例作为子类的原型

缺点: 父类新增原型方法/原型属性,子类都能访问到,父类一变其它的都变了

2、构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

缺点: 方法都在构造函数中定义, 只能继承父类的实例属性和方法,不能继承原型属性/方法,无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

3、组合继承

组合继承(所有的实例都能拥有自己的属性,并且可以使用相同的方法,组合继承避免了原型链和借用构造函数的缺陷,结合了两个的优点,是最常用的继承方式)

核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后再通过将父类实例作为子类原型,实现函数复用

缺点:调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

4、寄生组合继承

核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

缺点:堪称完美,但实现较为复杂

  • typeof的原理

不同的对象在底层都表现为二进制,在JavaScript中二进制前三位都为0的话,会被判断为object类型,
null的二进制全为0,自然前三位也是0,所以类型就是object.

  • 浅复制和深复制

浅复制:以赋值的形式复制引用对象,扔指向同一个地址,修改时原对象也会改变
    1.直接用 = ;
    2.Object.assign(target,...source);
    3.展开运算符...例:const ab = {...a,...b};
深复制:完全拷贝一个对象,新对象修改时不影响原对象
    1.JSON.Paser(JSON.String(obj)):性能最快
        具有循环引用的对象时报错
        当值为函数、undefined、symbol时无法拷贝
    2.借用jquery的:extend(true,target,source1)
    3.递归进行逐一复制
    const deepClone = function(origin,target){
        let tar = target || {};
        let toStr = object.prototype.toString;
        let arrStr = '[object Array]';

        for(let key in origin){
            if(tar.hasOwnProperty(origin[key])){
                if((typeof origin[key])==='object'&&origin[key]!==null){
                    if(toStr.cal(origin[key])===arrStr){
                        tar[key] = [];
                    }else{
                        tar[key] = {};
                    }
                    deepClone(origin[key],tar[key])
                }else{
                    tar[key] = origin[key]
                }

            }


        }


    }
    

四.  浏览器







五.   服务端与网络







六.   框架Vue

  • vue的生命周期有哪些,分别对应的作用是什么 ?

总共分为三个阶段:初始化、运行中、销毁
1. 实例、组件通过new Vue() 创建出来之后,先初始化事件和生命周期,然后就会执行beforeCreate钩子函数
    --数据还没有挂载,无法访问到数据和真实的dom,一般不做操作;
2. 挂载数据,绑定事件等等,然后执行created函数,--可以使用到数据,也可以更改数据,在这里更改数据不会
   触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在
   这里做初始数据的获取;
3. 找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子
   函数,--虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲
   染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取;
4. 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,--组件已经出现在页面中,数据、真实dom
   都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情...;
5. 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一
    次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿--这里不能更改数据,否则会陷入死
    循环;
6. 当更新完成后,执行updated--数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom--这里
   不能更改数据,否则会陷入死循环;
7. 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,--一般在这里做一些善后工作,例如清除
   计时器、清除非指令绑定的事件等等;
8. 组件的数据绑定、监听...去掉后只剩下dom空壳,这个时候,执行destroyed,--在这里做善后工作也可以

  • 父组件和子组件相互传值

父组件向子组件传值:
    方式1:1.父组件的data中定义值;2.在父组件中import调用,components注册,自定义标签使用子组件;
    3.在引用子组件的标签上用过v-bind:参数名='要传的值'(可以是数据也可以是方法),4.子组件通过
    props:['父组件绑定的参数名'](接收使用的名字和父组件自己定义的名字要一致),此时如果调用父组件
    的方法如果用到了父组件的变量,在子组件调用的时候,还是指向父组件的变量。
    方式2:vm.$broadcast(广播的yi)(事件名,数据) 父级向子级广播数据 配合:events:{} vue2.0已经弃用


子组件向父组件传值:1.在父组件中inmport调用,components注册,自定义标签使用子组件;2.在子组件方法
    中使用vm.$emit(事件名,数据);父组件中使用v-on:事件名 = '方法(接收的数据)'
  • vue常用的指令

1.v-model: 数据绑定;
2.v-for:循环;
3.v-show:显示 隐藏 (css);
4.v-if: 显示 隐藏(删除DOM);
5.v-else:不能单独使用;
6.v-else-if:不能单独使用;
7.v-bind:动态绑定 缩写:
8.v-on:绑定事件 缩写 @
9.v-text:解析文本
10.v-html:解析html标签
11.v-once:进入页面只进行一次渲染,不再进行渲染
12.v-cloak:防止闪烁
13.v-pre:把标签里的元素原位输出




七.   算法






八:其他

  • 常见的性能优化方式?

雅虎优化方案链接地址:https://www.jianshu.com/p/fe32ef31dee 

1.资源压缩合并,减少HTTP请求;
2.非核心代码异步加载--异步加载的方法--异步加载的区别
    异步加载的方式:动态脚本加载、defer(推迟)、async(异步)
    异步加载的区别:defer是在html解析完成以后才会执行,如果是多个,按照加载的顺序依次执行;
                   async是在加载完之后立即执行,如果是多个,执行顺序和加载顺序无关;
                   
3.利用浏览器缓存--缓存的分类--缓存的原理
    缓存:资源文件在浏览器的副本(放在本地电脑磁盘);
    强缓存:没有一个逻辑过程,直接拿过来使用;
    协商缓存:浏览器发现本地有这个副本但是又不确定用不用这个副本,和服务器确定一下本地副本能不能
             使用,是不是过期了;
    扩展:
    强缓存:
      我们在请求文件的时候HTTP响应头会携带一个或两个东西(这个要看服务器的配置),一个是
      Expires(过期时间),其对应的value值表示的是绝对时间,这个时间一般是从服务器下发的服务器的时间,
      判断客户端时间是否和服务器时间是否一致,在这个时间之前不会与服务器通信,直接从浏览器缓存拿资源;
      客户端的时间有可能和服务器的时间不一致,所以有一个Cache-Control,其对应值是max-age = 3600
      其表示的是相对时间,意思是我拿到资源之后,我在3600秒之内不会再去请求服务器,在这个时间之内
      都会从浏览器中拿缓存;服务器中两个时间都下发了,以Cache-Control对应的时间为准;
   协商缓存:
      当强缓存过期的时候,会进行协商缓存,当我拿到文件的时候浏览器会给HTTP头部添加
      Last-Modified(上次修改时间服务器下发的)这个key和value,下次我要确定资源有没有发生变化是
      通过HTTP请求头中的If-Modified-Since(请求时给服务器带的和Last-Modified是一个时间)便于
      服务器进行对比;If-Modified-Sine有一个缺点,虽然这个时间已经发生改变(相当于要求服务器下
      发资源),但是服务器上的资源没发生改变,这个时候可以通过Etag(服务器下发)判断;If-None_match
      的值就是服务器下发的Etag的值,页面再次请求的时候会把If-None-Match的值发送给服务器,如果没有
      改变将返回一个304状态,否则将返回一个200状态,并返回资源和新的Etag值;
        
            
    缓存的分类:强缓存:Expires(过期) Expires:Thu,21 jan 2017 23:39:02 GMT
                      Cache(电脑存储器)-Control Cache-Control:max-age=3600
               协商缓存:Last-Modified(上次修改) If-Modified-Since
                        Etag(可以认为是hash值) If-None-Match(匹配) 
                        Last-Modified:Wed,26 Jan 2017 00:35:11 GMT
                        
                        
4.使用CDN(网络快速到达服务端把文件下载下来)
5.预解析DNS(页面涉及多个域名的时候,预解析DNS效果很明显)
    meta 添加 <meta http-equiv(当量)="x-dns-prefetch-control" content="on">
    页面中的a标签是默认打开dns预解析的,但是如果页面是HTTPS协议开头,很多浏览器是会关闭a标签的预
    解析,上面这句话是强制打开a 标签的dns预解析;
    head 中添加 <link rel="dns-prefetch(预读)" href="//host_name_to_prefetch.com">