zoukankan      html  css  js  c++  java
  • 前端面试笔记(整理)

    1.CSS的盒子模型

    包含元素内容content、内边距padding、边框border、外边距margin
    box-sizing:border-box;content-box;inherit;
    1) content-box:总宽度=margin+border+padding+width,即为标准模型;
    2) border-box:总宽度=margin+width,即为IE模型;
    3) inherit:继承父元素的border-sizing属性。

    2.常见的post提交数据方式对应的content-type取值

    4
    1)application/x-www-form-urlencoded:数据被编码为名称/值对,这是标准的编码格式。
    2)multipart/form-data:数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
    3)application/json:告诉服务端消息主体是序列化后的 JSON 字符串.
    4)text/xml

    3.清除浮动的几种方法

    1)父级div定义伪类:afterzoom
    `.clearfloat::after {display:block; clear:both; content:" "; visibility:hidden; height:0;}
    .clearfloat {zoom:1}`
    2)在结尾处添加空div标签clear:both
    3)父级div定义height
    4)父级div定义display:table
    5)父级div也一起浮动
    6)父级div定义overflow:auto/hidden(必须定义widthzoom:1,同时不能定义height,浏览器会自动检查浮动区域的高度)

    4.移动端上click事件在某些浏览器有没有遇到延迟的问题

    1)静止缩放
    <meta name="viewport" content="width=device-width user-scalable='no' "> 
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
    2)引入`fastclick.js
    window.addEventListener(function(){

    FastClick.attach(document.body);

    1},false)`

    5.HTTP的缓存机制

    1)强制缓存:当所请求的数据在缓存数据库中尚未过期时,不与服务器进行交互,直接使用缓存数据库中的数据。
    Expire / Cache-Control
    2)协商缓存:从缓存数据库中取出缓存的标识,然后向浏览器发送请求验证请求的数据是否已经更新,如果已更新则返回新的数据,若未更新则使用缓存数据库中的缓存数据。
    etag / last-modifind

    6.实现三栏布局(左右两边固定宽度,中间自适应)

    1)浮动布局
    左右两边固定宽度,并分别设置float:leftfloat:right。(但这会带来高度塌陷的问题,所以要清除浮动。清除浮动的方式有:
    a. 给父级盒子设置height; 
    b.给父级盒子设置overflow:hidden; 
    c.在父级盒子结束前的盒子添加clear:both; 
    d.父级盒子也设置浮动; 
    e.父级div定义伪类:afterzoom

    .clear::after{display:block;clear:both;content:"";visibility:hidden;height:0;} 
    .clear{zoom:1;}

    2)绝对定位布局
    左中右三个盒子都设置position:absolute;然后分别设置定位
    3)flex布局
    父盒子设置display:flex;位于中间的子盒子设置flex:1
    4)表格布局
    父盒子设置display:table;左中右三个盒子设置display:table-cell;左右两个盒子分别设置宽度;
    5)网格布局
    父盒子设置display:gridgrid-template-columns:300px auto 300px;

    7.== 和 === 的区别

    ===为恒等符:当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回true,若等号两边的值类型不同时直接返回false

    ==为等值符: 当等号两边的值为相同类型时比较值是否相同,类型不同时会发生类型的自动转换,转换为相同的类型后再作比较。
    a、如果一个是null、一个是undefined,那么相等。
    b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
    c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 再比较。
    d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。 js核心内置类,会尝试valueOf先于toString;例外的是DateDate利用的是toString转换。那些不是JavaScript语言核心中的对象则通过各自的实现中定义的方法转换为原始值。
    e、任何其他组合,都不相等。

    8.transition和animation

    transition
    1)语法
    transition是一个复合属性,可设置四个过渡属性,简写方式如下:
    transition{ transition-property transition-duration transition-timing-function transition-delay}
    transition-property:是用来指定当元素其中一个属性改变时执行transition效果,值有none(没有属性改变)、all(默认值,所有属性改变),indent(某个属性名,一条transition规则,只能定义一个属性的变化,不能涉及多个属性,如果要设置多个属性时,需分别设置,中间以逗号隔开)【当其值为none时,transition马上停止执行,当指定为all时,则元素产生任何属性值变化时都将执行transition效果】;
    transition-duration:过度时间,是用来指定元素转换过程的持续时间,单位为s(秒)或ms(毫秒);
    transition-timing-function:时间函数,根据时间的推进去改变属性值的变换速率,值ease(逐渐变慢)、linear(匀速)、ease-in(加速)、ease-out(减速)、ease-in-out(加速然后减速)、cubic-bezier:(自定义一个时间曲线);
    transition-delay:延迟,指定一个动画开始执行的时间,也就是当改变元素属性值后多长时间开始执行transition效果,单位为s(秒)或ms(毫秒);
    2)触发方式
    伪类触发::hover,:focus,:checked,:active
    js触发:toggleClass
    3)以下情况下,属性值改变不能产生过渡效果
    a.background-image,如url(a.jpg)url(b.jpg)(与浏览器支持相关,有的浏览器不支持)等
    b.float浮动元素
    c.heightwidth使用auto
    d.display属性在none和其他值(block、inline-block、inline)之间变换
    e.positionstaticabsolute之间变换
    transition示例:

    <style>     
       #box2{
                height: 100px;
                 100px;
                background: blue;
            }
            #box2:hover{
                transform: rotate(180deg) scale(.5, .5);
                background: red;
                transition: background 2s ease, transform 2s ease-in 1s;}
        </style>
    </head>
    <body>
     <div id="box1">BOX1</div>
     <div id="box2">BOX2</div>
    </body>

    animation
    1)语法
    animation{ animation-name animation-duration animatino-timing-function animation-delay animation-iteration-count animation-direction animtion-play-state animation-fill-mode}
    animation-name:用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致;
    animation-duration:指定元素播放动画所持续的时间;
    animation-timing-function:和transition中的transition-timing-function 中的值一样。根据上面的@keyframes中分析的animation中可能存在多个小动画,因此这里的值设置是针对每一个小动画所在所在时间范围内的属性变换速率;
    animation-delay:定义在浏览器开始执行动画之前的等待的时间、这里是指整个animation执行之前的等待时间,而不是上面所说的多个小动画;
    animation-iteration-count:定义动画的播放次数,通常是整数,默认是1,若为infinity,动画将无限多次的播放;
    animation-direction:主要用来设置动画播放次数,其主要有两个值:normal:默认值,动画每次训话都是按顺序播放;alternate:动画播放在第偶数次向前播放,第奇数次想反方向播放(animation-iteration-count取值大于1时设置有效)
    animation-play-state:属性用来控制元素动画的播放状态。主要有两个值:running:可以通过该值将暂停的动画重新播放,这里的重新播放不是从元素动画的开始播放,而是从暂停的那个位置开始播放;paused:暂停播放。
    animation-fill-mod: 默认情况下,动画结束后,元素的样式将回到起始状态,animation-fill-mode属性可以控制动画结束后元素的样式。主要具有四个属性值:none(默认,回到动画没开始时的状态。),forwards(动画结束后动画停留在结束状态),backwords(动画回到第一帧的状态),both(根据animation-direction轮流应用forwardsbackwards规则)。
    animation示例:

    <style>
            .box{height:100px;100px;border:15px solid black;
                animation: changebox 10s ease-in-out   3 alternate paused;
                }
            .box:hover{
                animation-play-state: running;
            }
            @keyframes changebox {
                10% {  background:red;  }
                50% {  80px;  }
                70% {  border:15px solid yellow;  }
                100% {  180px;  height:180px;  }
            }
        </style>
    
    <body>
     <div class="box"></div>
    </body>
    9.事件冒泡  事件捕获

    事件冒泡,事件会从最内层的元素开始发生,一直向上传播,直到document对象;
    事件捕获则跟事件冒泡相反,事件会从document对象开始发生,直到最具体的元素;

    10.GET和POST的区别

    1.发送方式:GET请求数据放在url上,即HTTP的协议头中;而POST把数据放在HTTP的包体中。
    2.大小的限制:GET传的参数有长度的限制,因为浏览器对url的长度有限制;而POST理论上是没有限制的。
    3.安全性:GET请求可被缓存,请求保存在浏览器的历史记录中;POST则不能被缓存。与POST相比,GET的安全性较差,因为发送的数据是URL的一部分。

    11.var的变量提升的底层原理是什么?

    JS引擎的工作方式是
    1)先解析代码,获取所有被声明的变量;
    2)然后再执行。
    也就是分为预处理和执行这两个阶段。
    变量提升:所有用var声明变量的语句都会被提升到代码头部。另外function也可看作变量声明,也存在变量提升的情况。

    12.垂直水平居中的方式?

    1)定位
    父元素设置为:position: relative
    子元素设置为:position: absolute
    距上50%,据左50%,然后减去元素自身宽度的距离就可以实现

     100px;
    height: 100px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -50px 0 0 -50px;

    2)flex布局

    display: flex; //flex布局
    justify-content: center; //使子项目水平居中
    align-items: center; //使子项目垂直居中

    3)tabel-cell

    display: table-cell;
    vertical-align: middle;//使子元素垂直居中
    text-align: center;//使子元素水平居中
    13.如何判断一个对象是否为数组

    1) Array.prototype.isPrototypeOf(obj)方法,判定Array是不是在obj的原型链中,如果是,则返回true,否则false;
    2) obj instanceof Array;
    3) Object.prototype.toString.call(obj);(==="[object Array]")
    4) Array.isArray(obj);

    14.margin塌陷?

    当两个盒子在垂直方向上设置margin值时,会出现塌陷现象
    解决方法:

    1.给父盒子添加border
    2.给父盒子添加padding-top
    3.给父盒子添加overflow:hidden
    4.父盒子:position:fixed
    5.父盒子:display:table
    6.给子元素的前面添加一个兄弟元素
      属性为:content:"";
      overflow:hidden;

    解决方法的主要原理就是设置盒子为BFC
    BFC为页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。

    15.伪类与伪元素的区别

    1)伪类
    伪类用于选择DOM树之外的信息,或是不能用简单选择器进行表示的信息。前者包含那些匹配指定状态的元素,比如:link,:visited,:hover,:active;后者包含那些满足一定逻辑条件的DOM树中的元素,比如:first-child,:first-of-type,:target
    2)伪元素
    伪元素为DOM树没有定义的虚拟元素。不同于其他选择器,它不以元素元素为最小选择单元,它选择的是元素制定单元。比如::before表示选择元素内容的之前内容;::selection表示选择元素被选中的内容。
    3)伪类/伪元素一览表
    <伪类如下>

    /*
    :active      选择正在被激活的元素
    :hover         选择被鼠标悬浮着元素
    :link        选择未被访问的元素
    :visited     选择已被访问的元素
    :first-child 选择满足是其父元素的第一个子元素的元素    
    :lang         选择带有指定 lang 属性的元素
    :focus       选择拥有键盘输入焦点的元素
    :enable      选择每个已启动的元素
    :disable     选择每个已禁止的元素
    :checked     选择每个被选中的元素    
    :target      选择当前的锚点元素
    */

    <伪元素如下>

    /*
    ::first-letter    选择指定元素的第一个单词
    ::first-line      选择指定元素的第一行
    ::after           在指定元素的内容后面插入内容
    ::before          在指定元素的内容前面插入内容
    ::selection       选择指定元素中被用户选中的内容
    */
    16.介绍一下JS的基本数据类型

    Undefined,Null,Boolean,Number,String

    17.JavaScript的typeof返回那些数据类型

    undefined,string,boolean,number,symbol(ES6),object,function

    18.介绍一下JS有哪些内置对象?

    数据封装类对象:Object、Array、Boolean、Number、String 
    其他对象:Function、Argument、Math、Date、RegExp、Error

    19.null和undefined的区别

    1)null表示一个对象被定义了,值为“空值”;undefined表示不存在这个值。
    2)变量被定义了,但是没有赋值时,就等于undefined
    3)注意:在验证null时,要用===,因为==无法区分nullundefined
    typeof null // "object" 说明:null是一个没有任何属性和方法的对象

    20.对JSON的了解

    1) JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。 
    2) 它是基于JavaScript的一个子集。数据格式简单,易于读写,占用带宽小。 如:{"age":"12", "name":"back"}

    21.列举3种强制类型转换和2种隐式类型转换

    强制:parseInt(),parseFloat(),Number(),(Boolean(),String()
    隐式:==

    22.input的type属性有哪些?

    text:文本框
    password:密码
    radio:单选按钮
    checkbox:复选框
    file:文件选择域
    hidden:隐藏域
    button:按钮
    reset:重置按钮
    submit:表单提交按钮
    image:图片按钮

    23.IE和标准下有哪些兼容性的写法
    var ev = ev || window.event
    document.documentElement.clientWidth || document.body.clientWidth
    var target = ev.srcElement||ev.target
    24.如何阻止事件冒泡

    ie:阻止冒泡ev.cancelBubble = true;
    IE ev.stopPropagation();

    25.如何阻止默认事件

    1)return false;2) ev.preventDefault();

    26.说说前端中的事件流?

    事件流描述的是从页面接收事件的顺序,DOM2级事件流包括下面几个阶段。
    事件捕获阶段
    处理事件阶段
    事件冒泡阶段
    addEventListeneraddEventListenerDOM2级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值。最后的布尔值如果为true,表示在捕获阶段调用事件处理程序;如果为false,表示在冒泡阶段调用事件处理程序,默认为false

    27.如何实现一个自适应的正方形

    1)CSS 3vw单位
    CSS3中新增了一组相对于可视区域百分比的长度单位vw、vh、vmin、vmax。其中vw是相对于视口宽度百分比的单位,1vw=1%viewport widthvh是相对于视口高度百分比的单位,1vh=1%viewport heightvmin是相对于当前视口宽高中较小的一个的百分比单位,同理vmax是相对当前视口宽高中较大的一个百分比单位。
    代码实现:

    .placeholder{
       50vw;
      height: 50vw;
    }

    优点:简洁方便
    缺点:浏览器兼容不好
    2)设置垂直方向的 padding 撑开容器
    margin、padding的百分比数值是相对于父元素宽度计算的。由此可以发现只需要将元素垂直方向的padding值设定为与width相同的百分比就可以制作出自适应正方形了:
    代码实现:

    .placeholder{
       100%;
      padding-bottom:100%;
    }

    如果正方形中没有内容(相当于只是一个几何里面的正方形,并没有展示其他任何内容),一切看起来都很正常;但是,如果正方形中有其他内容(这种情况会更常见一些,比如说有一些文本和图片),此时容器的高度就会被拉伸,因为盒子模型中的padding 是不包含在 content 中的,所以我们可以通过 height:0 解决这个问题;这种方案简洁明了,且兼容性好;但是除了填充内容后会出现问题以外,还有可能碰上max-height不收缩,于是第三种方案来了:
    3)利用伪元素的margin(padding)-top撑开容器
    在方案二中,我们利用百分比数值的 padding-bottom 属性撑开容器内部空间,但是这样做会导致在元素上设置的 max-height 属性失效;而失效的原因是 max-height 属性只限制于 height,也就是只会对元素的 content height 起作用。那么我们是不是能用一个子元素撑开 content 部分的高度,从而使 max-height 属性生效呢?我们来试试:

     
            .placeholder {
                 20%;
                background-color: #000;
    
                /* overflow: hidden; */
                /* display: inline-block; */
                float: left;
                /*设置成BFC才能使margin-top撑起高度*/
            }
            
            .placeholder:after {
                content: '';
                display: block;
                margin-top: 100%;
                /* margin 百分比相对父元素宽度计算 */
            }
    28.js中的位置关系

    offsetParent:该属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),已进行过CSS定位的容器元素。 如果这个容器元素未进行CSS定位, 则offsetParent属性的取值为body元素的引用。 当容器元素的style.display 被设置为 "none"时(译注:IEOpera除外),offsetParent属性 返回 null
    top:该属性一般对用过css定位的元素有效(position“static”时为auto,不产生效果),定义了一个top属性有效的元素(即定位元素)的上外边距边界与其包含块上边界之间的偏移。
    clientTop:元素上边框的厚度,当没有指定边框厚底时,一般为0
    scrollTop:位于对象最顶端和窗口中可见内容的最顶端之间的距离,简单地说就是滚动后被隐藏的高度。
    offsetTop:获取对象相对于由offsetParent属性指定的父坐标(css定位的元素或body元素)距离顶端的高度。
    clientHeight:内容可视区域的高度,也就是说页面浏览器中可以看到内容的这个区域的高度,一般是最后一个工具条以下到状态栏以上的这个区域,与页面内容无关。
    scrollHeightIEOpera 认为 scrollHeight 是网页内容实际高度,可以小于clientHeightFF 认为scrollHeight 是网页内容高度,不过最小值是 clientHeight
    offsetHeight:获取对象相对于由offsetParent属性指定的父坐标(css定位的元素或body元素)的高度。IEOpera 认为 offsetHeight = clientHeight + 滚动条 + 边框。FF 认为 offsetHeight 是网页内容实际高度,可以小于clientHeightoffsetHeight在新版本的FF和IE中是一样的,表示网页的高度,与滚动条无关,chrome中不包括滚动条。

    *诸如left、clientLeft、offsetLeft、clientWidth、scrollWidth等,和top、height类似,不再赘述。

    clientXclientY:相对于浏览器窗口可视区域的XY坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性。
    pageXpageY:类似于event.clientXevent.clientY,但它们使用的是文档坐标而非窗口坐标。这2个属性不是标准属性,但得到了广泛支持。IE事件中没有这2个属性。
    offsetXoffsetY:相对于事件源元素(targetsrcElement)的X,Y坐标,只有IE事件有这2个属性,标准事件没有对应的属性。
    screenXscreenY:相对于用户显示器屏幕左上角的X,Y坐标。标准事件和IE事件都定义了这2个属性

     
    29.Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?

    Doctype声明于文档最前面,告诉浏览器以何种方式来渲染页面,这里有两种模式,严格模式和混杂模式。
    严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
    混杂模式,向后兼容,模拟老式浏览器,防止浏览器无法兼容页面。

    30.link标签和import标签的区别?

    link属于html标签,而@importcss提供的
    页面被加载时,link会同时被加载,而@import引用的css会等到页面加载结束后加载。
    linkhtml标签,因此没有兼容性,而@import只有IE5以上才能识别。
    link方式样式的权重高于@import的。

    31.元素的文本省略号?

    单行:

     overflow:hidden;
     text-overflow:ellipsis;
     white-space:nowrap

    多行:
    1)直接用css属性设置(只有-webkit内核才有作用)

    display: -webkit-box
    -webkit-box-orient:vertical
    -webkit-line-clamp:3
    overflow:hidden

    移动端浏览器绝大部分是WebKit内核的,所以该方法适用于移动端;
    -webkit-line-clamp 用来限制在一个块元素显示的文本的行数,这是一个不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
    display: -webkit-box 将对象作为弹性伸缩盒子模型显示 。
    -webkit-box-orient 设置或检索伸缩盒对象的子元素的排列方式 。
    text-overflow: ellipsis 以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本。

    32.XML和JSON的区别?

    1)数据体积方面
    JSON相对于XML来讲,数据的体积小,传递的速度更快些
    2)数据描述方面
    JSONJavaScript交互更加方便,更容易解析处理,更容易交互
    3)数据描述方面
    JSON对数据的描述性比XML
    4)传输速度方面
    JSON的速度要远远快于XML

    33.前端需要注意哪些SEO?

    合理的titledescriptionkeywords:搜索对着三项的权重逐个减少,title值强调重点即可,重要关键词不要超过两次,而且要靠前,不同页面的title要有所不同;
    description把页面的内容高度概括,长度合适,不可过分分堆砌关键词,不同页面的description有所不同;
    keywords列举重要关键词即可;

    // title标题
    <title>标题</title>
    // keywords 关键词
    <meta name="description" content="关键词1,关键词2,关键词3">
    // description 内容摘要
    <meta name="description" content="网页的简述">

    语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页;
    重要内容的HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,有的搜索引擎对抓取长度有限制,所以要保证重要内容一定会被抓取;
    重要内容不要用JS输出:爬虫不会执行JS获取内容;
    少用iframe:搜索引擎不会抓取iframe中的内容;
    非装饰性图片必须加alt
    提高网站速度:网站速度是搜素引擎排序的一个重要指标;

    34.HTTP的几种请求方法用途?

    1)GET方法
    发送一个请求来取得服务器上的某一资源
    2)POST方法
    URL指定的资源提交数据或附加新的数据
    3)PUT方法
    POST方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT指定了资源在服务器上的位置,而POST没有
    4)HEAD方法
    只请求页面的首部
    5)DELETE方法
    删除服务器上的某资源
    6)OPTIONS方法
    它用于获取当前URL所支持的方法。如果请求成功,会有一个Allow的头包含类似“GET,POST”这样的信息
    7)TRACE方法
    TRACE方法被用于激发一个远程的,应用层的请求消息回路
    8)CONNECT方法
    把请求连接转换到透明的TCP/IP通道

    35.如何进行网页性能优化?

    1)content方面
    减少HTTP请求:合并文件、CSS精灵图
    减少DNS查询:DNS缓存、将资源分布到恰当数量的主机名
    减少DOM元素数量
    2)Server方面
    使用CDN
    配置ETag
    对组件使用Gzip压缩
    3)Cookie方面
    减少cookie大小
    4)CSS方面
    将样式表放到页面顶部
    不使用CSS表达式
    使用<link>不使用@import
    5)JavaScript方面
    将脚本放到页面底部
    JavaScriptCSS从外部引入
    压缩JavaScriptCSS
    删除不需要的脚本
    减少DOM访问
    6)图片方面
    优化CSS精灵
    不要再HTML中拉伸图片

    36.语义化的理解

    HTML语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;
    在没有CSS样式情况下也以一种文档格式显示,并且是容易阅读的;
    搜索引擎的爬虫依赖于标记来确定上下文的各个关键字的权重,利于SEO
    使阅读源代码的人更容易将网站分块,便于阅读维护理解;

    37.WEB标准以及W3C标准是什么

    标签闭合、标签小写、不乱嵌套、使用外链CSSJS、结构行为表现的分离

    38.说说对作用域链的理解

    作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的;
    即作用域就是变量与函数的可访问范围,即作用域控制这变量与函数的可见性和生命周期;

    39.原生JS都有哪些方式可以实现两个页面间的通信?

    1)通过url地址栏传递参数;
    例如:点击列表中的每一条数据,跳转到一个详情页面,在URL中传递不同的参数区分不同的页面;
    2)通过本地存储cookielocalStoragesessionStorage
    例如京东的登陆,把登陆后获得的页面信息存储到本地,其他页面需要用户信息的话就从本地的存储数据中获取;
    3)使用iframe
    例如在页面中嵌入页面,在中可以通过一些属性和实现方法和页面的通信;
    4)利用postMessage实现页面间的通信
    例如父窗口往子窗口传递信息,子窗口往父窗口传递信息

    40.ES6中的let,const,var的区别是什么?

    var:声明全局常量;
    let:声明块级常量,即局部常量,定以后可以修改;
    const:用于声明常量,定义后不能再修改值或者引用值的常量,也具有块级作用域;

    41.对数组进行去重,es5或者es6方法
    //es5四种方式:
    
    //方式一:
    Array.prototype.unique1 = function() {
        // 1. 定义数组
        var temp = [];
        // 2. 遍历当前数组
        for(var i = 0; i < this.length; i++) {
            // 3.如果当前数组的第i已经保存进了临时数组,
            // 那么跳过,否则把当前项push到临时数组里面
            if (-1 === temp.indexOf(this[i])) {
                temp.push(this[i]);
            }
        }
        return temp;
    };
    
    //方式二:
    Array.prototype.unique2 = function() {
        //1. hash为hash表,r为临时数组
        var hash = {}, temp=[];
        // 2.遍历当前数组
        for(var i = 0; i < this.length; i++)
        {
            // 3. 如果hash表中没有当前项
            if (!hash[this[i]])
            {
                // 4.存入hash表
                hash[this[i]] = true;
                // 5.把当前数组的当前项
                // push到临时数组里面
                temp.push(this[i]);
            }
        }
        return temp;
    };
    
    //方式三:
    Array.prototype.unique3 = function() {
        var n = [this[0]];
        for(var i = 1; i < this.length; i++){
            if (this.indexOf(this[i]) === i) {
                n.push(this[i]);
            }
        }
        return n;
    };
    
    //方式四:
    Array.prototype.unique4 = function() {
        this.sort();
        var re=[this[0]];
        for(var i = 1; i < this.length; i++)
        {
            if( this[i] !== re[re.length-1])
            {
                re.push(this[i]);
            }
        }
        return re;
    };
    
    //es6实现方式:
    
    Array.prototype.unique =
    Array.prototype.unique 
    || function () {
        return [...new Set(this)];
    };
    42.页面加载过程中可能触发哪些事件?它们的顺序是?

    页面加载时,大致可以分为以下几个步骤:
    1)开始解析HTML文档结构
    2)加载外部样式表及JavaScript脚本
    3)解析执行JavaScript脚本
    4)DOM树渲染完成
    5)加载未完成的外部资源(如 图片)
    6)页面加载成功
    执行顺序:
    1)document readystatechange事件
    2)document DOMContentLoaded事件
    3)window load事件

    43.什么是CDN,CDN对于网络有什么意义,它有什么的缺点?

    CDN又称为内容分发网络;本意在于尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。
    主要目的:解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点的加速、点播、直播等场景。使用户就近取得所需内容,解决Internet网络拥挤的状况,提高用户访问网站的响应速度和成功率。
    缺点:1)实施复杂,投资大
    2)目前大部分的CDN还只是对静态的内容加速,对动态加速效果不好;而双线对动态加速的效果跟静态是一样的。

    44.vue-router中$route和$router的区别?

    1)$route为当前router跳转对象里面可以获取namepathqueryparams
    2)$routerVueRouter实例,想要导航到不同URL,则使用$router.push方法
    返回上一个history也是使用$router.go方法

    45.vue路由传参query与params两种方式的区别

    query要用path来引入,例如ths.$router.push({ path:"detail",query:{id:"00"}}),接收参数为this.$route.query.idparams要用name来引入,例如ths.$router.push({ name:"detail",params:{id:"00"}}),接收参数为this.$route.params.id。以query传输的参数会在类似于get传参,在浏览器地址栏中显示参数。

    46.描述一下渐进增强和优雅降级

    优雅降级(graceful degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。
    渐进增强(progressive enhancement):一开始只构建站点的最少特性,然后不断针对各浏览器追加功能。

    47.为什么利用多个域名来请求网络资源会更有效?

    动静分离请求,使用不同的服务器处理请求,提高效率;
    突破浏览器的并发限制,同一时间针对同一域名下的请求有一定的数量限制。
    节约主域名的连接数,从而提高客户端网络带宽的利用率,优化页面响应。

    48.HTML5有哪些新特性、移除了哪些元素?

    1)绘画标签canvas
    2)用于媒介回放的videoaudio元素;
    3)本地离线存储localStorage长期存储数据,浏览器关闭后数据不丢失;
    4)sessionStorage的数据在浏览器关闭后自动删除;
    5)语义化更好的内容元素,比如articlefooterheadernavsection
    6)表单控件,calendardatatimeemailurlsearch
    7)webworkerwebsocketGeolocation
    移除的元素:
    1)纯表现的元素:basefontbigcenterfontsstrikett
    2)对可用性产生负面影响的元素:frameframesetnoframes

    49.display:none;与visibility:hidden;的区别?

    相同点:它们都能让元素不可见‘
    不同点:
    display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间;
    visibility:hidden;不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见;
    display:none;是非继承属性,子孙节点的消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示;
    visibility:hodden;是继承属性,子孙节点的消失由于继承了hidden,通过设置visibility:visible;可以让子孙节点显示;
    修改常规流中元素的display通常会造成文档重排。修改visibility属性只会造成本元素的重绘;
    读屏器不会读取display:none;元素内容;会读取visibility:hidden;元素内容;

    50.CSS去掉inline-block元素间隙的几种方法?

    间隙是怎么来的:间隙是由换行或者回车导致的;只要把标签写成一行或者标签没有空格,就不会出现间隙;
    去除方法:
    方法一:
    元素间的间隙出现的原因,是元素标签之间的空格,把空格去掉间隙就会消失

    <div class="itlike">
      <span>lhh</span><span>lhh</span>
    </div>

    方法二:
    利用HTML注释标签

    <div class="demo">
        <span>lhh</span><!-- 
        --><span>lhh</span>
    </div>

    方法三:
    取消标签闭合

    <div class="demo">
        <span>lhh
        <span>lhh
        <span>lhh
        <span>lhh
    </div>

    方法四:
    在父容器上使用font-size:0;可以消除间隙

    <div class="demo">
        <span>lhh</span>
        <span>lhh</span>
        <span>lhh</span>
        <span>lhh</span>
    </div>
    .demo {font-size: 0;}

    51.apply,call,bind有什么区别?

    三者都可以把一个函数应用到其他对象上,apply,call是直接执行函数调用,bind是绑定,执行需要再次调用。 
    applycall的区别是apply接受数组作为参数,而call是接受逗号分隔的无限多个参数列表。
    代码如下:

    function Person() {
        }
        Person.prototype.sayName() { alert(this.name); }
    
        var obj = {name: 'michaelqin'}; // 注意这是一个普通对象,它不是Person的实例
        // 1) apply
        Person.prototype.sayName.apply(obj, [param1, param2, param3]);
    
        // 2) call
        Person.prototype.sayName.call(obj, param1, param2, param3);
    
        // 3) bind
        var liaoke = Person.prototype.sayName.bind(obj);    
        liaoke ([param1, param2, param3]); // bind需要先绑定,再执行 
        liaoke (param1, param2, param3); // bind需要先绑定,再执行
    

    52.介绍一下defineProperty,hasOwnProperty, propertyIsEnumerable

    Object.defineProperty(obj,prop,descriptor)用来给对象定义属性,有value,writeable,enumerable,set/get,configurable
    hasOwnProperty用于检查某一属性是不是存在于对象本身,
    propertyIsEnumerable用来检测某一属性是否可遍历,也就是能不能用for...in循环来取到。

    53.JS常用设计模式的实现思路(单例、工厂、代理、装饰、观察者模式等)

    // 1) 单例: 任意对象都是单例,无须特别处理
        var obj = {name: 'michaelqin', age: 30};
    
     // 2) 工厂: 就是同样形式参数返回不同的实例
        function Person() { this.name = 'Person1'; }
        function Animal() { this.name = 'Animal1'; }
    
        function Factory() {}
        Factory.prototype.getInstance = function(className) {
            return eval('new ' + className + '()');
        }
    
        var factory = new Factory();
        var obj1 = factory.getInstance('Person');
        var obj2 = factory.getInstance('Animal');
        console.log(obj1.name); // Person1
        console.log(obj2.name); // Animal1
    
     // 3) 代理: 就是新建个类调用老类的接口,包一下
        function Person() { }
        Person.prototype.sayName = function() { console.log('michaelqin'); }
        Person.prototype.sayAge = function() { console.log(30); }
    
        function PersonProxy() { 
            this.person = new Person();
            var that = this;
            this.callMethod = function(functionName) {
                console.log('before proxy:', functionName);
                that.person[functionName](); // 代理
                console.log('after proxy:', functionName);
            }
        }
    
        var pp = new PersonProxy();
        pp.callMethod('sayName'); // 代理调用Person的方法sayName()
        pp.callMethod('sayAge'); // 代理调用Person的方法sayAge() 
    
      // 4) 观察者: 就是事件模式,比如按钮的onclick这样的应用.
        function Publisher() {
            this.listeners = [];
        }
        Publisher.prototype = {
            'addListener': function(listener) {
                this.listeners.push(listener);
            },
    
            'removeListener': function(listener) {
                delete this.listeners[listener];
            },
    
            'notify': function(obj) {
                for(var i = 0; i < this.listeners.length; i++) {
                    var listener = this.listeners[i];
                    if (typeof listener !== 'undefined') {
                        listener.process(obj);
                    }
                }
            }
        }; // 发布者
    
        function Subscriber() {
    
        }
        Subscriber.prototype = {
            'process': function(obj) {
                console.log(obj);
            }
        }; // 订阅者
    
        var publisher = new Publisher();
        publisher.addListener(new Subscriber());
        publisher.addListener(new Subscriber());
        publisher.notify({name: 'michaelqin', ageo: 30}); // 发布一个对象到所有订阅者
        publisher.notify('2 subscribers will both perform process'); // 发布一个字符串到所有订阅者

    54.处理字符串常用的十个函数

    charAt()   // 返回在指定位置的字符。
    concat()   // 连接字符串。
    fromCharCode()   // 从字符编码创建一个字符串。
    indexOf()  // 检索字符串。
    match()   // 找到一个或多个正则表达式的匹配。
    replace()   // 替换与正则表达式匹配的子串。
    search()   // 检索与正则表达式相匹配的值。
    slice()   // 提取字符串的片断,并在新的字符串中返回被提取的部分。
    split()   // 把字符串分割为字符串数组。
    substr()   // 从起始索引号提取字符串中指定数目的字符。
    substring()   // 提取字符串中两个指定的索引号之间的字符。
    toLocaleLowerCase()   // 把字符串转换为小写。
    toLocaleUpperCase()   // 把字符串转换为大写。
    toLowerCase()   // 把字符串转换为小写。
    toUpperCase()   // 把字符串转换为大写。
    toString()   // 返回字符串。
    valueOf()   // 返回某个字符串对象的原始值。

    55.如何判断一个变量是对象还是数组

    function isObjArr(variable){
         if (Object.prototype.toString.call(value) === "[object Array]") {
                console.log('value是数组');
           }else if(Object.prototype.toString.call(value)==='[object Object]'){//这个方法兼容性好一点
                console.log('value是对象');
          }else{
              console.log('value不是数组也不是对象')
          }
    }
    
    // 注意:千万不能使用typeof来判断对象和数组,因为这两种类型都会返回"object"。

    56.ES5的继承和ES6的继承有什么区别?

    ES5的继承是通过prototype或构造函数机制来实现。
    ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this))。
    ES6的继承机制实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this。具体为ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须在constructor方法中调用super方法,否则新建实例报错。因为子类没有自己的this对象,而是继承了父类的this对象,然后对其调用。如果不调用super方法,子类得不到this对象。

    注意:super关键字指代父类的实例,即父类的this对象。在子类构造函数中,调用super后,才可使用this关键字,否则报错。

    57.下面的ul,如何点击每一列的时候alert其index?(闭包)

     <ul id="test">
     <li>这是第一条</li>
     <li>这是第二条</li>
    <li>这是第三条</li>
     </ul>
    
    
    // 方法一:
    var lis=document.getElementById('test').getElementsByTagName('li');
    for(var i=0;i<3;i++)
    {
    lis[i].index=i;
    lis[i].onclick=function(){
    alert(this.index);
    };
    }
    
    //方法二:
    var lis=document.getElementById('test').getElementsByTagName('li');
    for(var i=0;i<3;i++)
    {
    lis[i].index=i;
    lis[i].onclick=(function(a){
    return function() {
    alert(a);
    }
    })(i);
    }

    58.对于MVVM的理解

    MVVM 是 Model-View-ViewModel 的缩写。
    Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
    View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
    ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,
    简单理解就是一个同步View 和 Model的对象,连接ModelView
    MVVM架构下,View 和 Model 之间并没有直接的联系,
    而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的,
    因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
    ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,
    View 和 Model 之间的同步工作完全是自动的,无需人为干涉,
    因此开发者只需关注业务逻辑,不需要手动操作DOM
    不需要关注数据状态的同步问题,
    复杂的数据状态维护完全由 MVVM 来统一管理。

    59.解释Vue的生命周期

    Vue实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom->渲染、更新->渲染、销毁等一系列过程,称之为Vue的生命周期。

    Vue的生命周期包括:
    beforeCreate(创建前)在数据观测和初始化事件还未开始,
    created(创建后)完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来;
    beforeMount(载入前)在挂载开始之前被调用,相关的render函数首次被调用,实例已完成以下的配置:编译模板,把data里面的数据和模板生成html,注意此时还没有挂载html到页面上;
    mounted(载入后)在el被新创建的vm.$el替换,并挂载到实例上去之后调用,实例已完成以下配置:用上面编译好的html内容替换el属性指向的DOM对象,完成模板中的html渲染到html页面中,此过程中进行ajax交互。
    beforeUpdate(更新前)在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
    updated(更新后)在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器渲染期间不被调用。
    beforeDestroy(销毁前)在实例销毁之前调用,实例仍然完全可用。
    destroyed(销毁后)在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

    60.为什么使用Node.js,它有哪些优缺点?

    优点:
    事件驱动,通过闭包很容易实现客户端的生命活期。
    不用担心多线程,锁,并行计算的问题
    V8引擎速度非常快
    对于游戏来说,写一遍游戏逻辑代码,前端后端通用
    缺点:
    node.js更新很快,可能会出现版本兼容
    node.js还不算成熟,还没有大制作
    node.js不像其他的服务器,对于不同的链接,不支持进程和线程操作

    61.什么是错误优先的回调函数?

    错误优先(Error-first)的回调函数(Error-First Callback)用于同时返回错误和数据。
    第一个参数返回错误,并且验证它是否出错;其他参数返回数据。

    fs.readFile(filePath, function(err, data)
    {
        if (err)
        {
            // 处理错误
            return console.log(err);
        }
        console.log(data);
    });

    62.使用npm有哪些好处?

    通过npm,你可以安装和管理项目的依赖,
    并且能够指明依赖项的具体版本号。
    对于Node应用开发而言,
    可以通过package.json文件来管理项目信息,
    配置脚本,以及指明依赖的具体版本。

    63.在JavaScript源文件的开头包含 use strict 有什么意义和好处?

    use strict 是一种在JavaScript代码运行时自动实行更严格解析和错误处理的方法。(严格模式)
    将值分配给一个未声明的变量会自动创建该名称的全局变量。这是JavaScript中最常见的错误之一。在严格模式下,这样做的话会抛出错误。消除 this 强制。
    当检测到对象(例如,var object = {foo: "bar", foo: "baz"};)中重复命名的属性,或检测到函数中(例如,function foo(val1, val2, val1){})重复命名的参数时,严格模式会抛出错误,因此捕捉几乎可以肯定是代码中的bug可以避免浪费大量的跟踪时间。比eval() 更安全。

    64.vuejs与angularjs以及react的区别?

    AngularJS的区别
    相同点:
    都支持指令:内置指令和自定义指令。
    都支持过滤器:内置过滤器和自定义过滤器。
    都支持双向数据绑定。
    都不支持低端浏览器。
    不同点:
    1.AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观。
    2.在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢。
    Vue.js使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。
    对于庞大的应用来说,这个优化差异还是比较明显的。

    React的区别
    相同点:
    React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。
    中心思想相同:一切都是组件,组件实例之间可以嵌套。
    都提供合理的钩子函数,可以让开发者定制化地去处理需求。
    都不内置列数AJAXRoute等功能到核心包,而是以插件的方式加载。
    在组件开发中都支持mixins的特性。
    不同点:
    React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。
    Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM

    65.标签keep-alive的作用是什么?

    <keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。

    66.WeakMap 和 Map 的区别?

    WeakMap 结构与 Map 结构基本类似,唯一的区别是它只接受对象作为键名( null 除外),不接受其他类型的值作为键名,而且键名所指向的对象,不计入垃圾回收机制。
    WeakMap 最大的好处是可以避免内存泄漏。一个仅被 WeakMap 作为 key 而引用的对象,会被垃圾回收器回收掉。
    WeakMap 拥有和 Map 类似的 set(key, value) 、get(key)has(key)delete(key) 和 clear() 方法, 没有任何与迭代有关的属性和方法。

    67.http和https的基本概念?

    http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
    https: 是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL
    https协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。

    68.git fetch和git pull的区别?

    git pull:相当于是从远程获取最新版本并merge到本地
    git fetch:相当于是从远程获取最新版本到本地,不会自动merge

    69.介绍一下对浏览器内核的理解?

    主要分成两部分:渲染引擎(layout engineerRendering Engine)和JS引擎。
    渲染引擎:负责取得网页的内容(HTMLXML、图像等等)、
    整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。
    浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。
    所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
    JS引擎:解析和执行javascript来实现网页的动态效果。
    最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。

    70.什么是微格式

    微格式(Microformats)是一种让机器可读的语义化XHTML词汇的集合,是结构化数据的开放标准。
    是为特殊应用而制定的特殊格式
    优点:将智能数据添加到网页上,让网站内容在搜索引擎结果界面可以显示额外的提示。

    71.数据绑定基本的实现

     // 实现一个方法,可以给 obj 所有的属性添加动态绑定事件,当属性值发生变化时会触发事件
    let obj = {
      key_1: 1,
      key_2: 2
    }
    function func(key) {
      console.log(key + ' 的值发生改变:' + this[key]);
    }
    bindData(obj, func);
    obj.key_1 = 2; // 此时自动输出 "key_1 的值发生改变:2"
    obj.key_2 = 1; // 此时自动输出 "key_2 的值发生改变:1"

    答案:

     
    function bindData(obj, fn) {
      for (let key in obj) {
        Object.defineProperty(obj, key, {
          set(newVal) {
            if (this.value !== newVal) {
              this.value = newVal;
              fn.call(obj, key);
            }
          },
          get() {
            return this.value;
          }
        })
      }
    }

    72.介绍一下对webpack的认识?

    WebPack 是一个模块打包工具,可以使用WebPack管理模块依赖,并编绎输出模块们所需的静态文件。
    它能够很好地管理、打包Web开发中所用到的HTMLjavaScriptCSS 以及各种静态文件(图片、字体等),让开发过程更加高效。
    对于不同类型的资源,webpack 有对应的模块加载器。webpack 模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。
    webpack的两大特色:
    1)code splitting(可以自动完成)
    2)loader 可以处理各种类型的静态文件,并且支持串联操作
    webpack 是以commonJS的形式来书写脚本,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
    webpack具有requireJsbrowserify的功能,但仍有很多自己的新特性:
    1) 对 CommonJS 、 AMD 、ES6的语法做了兼容
    2) 对jscss、图片等资源文件都支持打包
    3) 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对CoffeeScriptES6的支持
    4) 有独立的配置文件webpack.config.js
    5) 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间
    6) 支持 SourceUrls 和 SourceMaps,易于调试
    7) 具有强大的Plugin接口,大多是内部插件,使用起来比较灵活
    8)webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快

    73.关于HTTP2.0的认识

    HTTP/2引入了“服务端推(server push)”的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。
    HTTP/2提供更多的加密支持,HTTP/2使用多路技术,允许多个消息在一个连接上同时交差。
    它增加了头压缩(header compression),因此即使非常小的请求,其请求和响应的header都只会占用很小比例的带宽。

    74.对AMD和Commonjs的理解?

    CommonJS是服务器端模块的规范,nodejs采用了这个规范。
    CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。
    AMD规范则是非同步加载模块,允许指定回调函数。
    AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exportsexports
    属性赋值来达到暴露模块对象的目的。

    75.mongoDB和MySQL的区别?

    MySQL是传统的关系型数据库,MongoDB则是非关系型数据库
    mongodbJSON结构(二进制)进行存储,对海量数据存储有着很明显的优势。
    对比传统关系型数据库,NoSQL有着非常显著的性能和扩展性优势,与关系型数据库相比,MongoDB的优点有: 
    ①弱一致性(最终一致),更能保证用户的访问速度: 
    ②文档结构的存储方式,能够更便捷的获取数据。

    76.讲讲304缓存的原理?

    服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。
    本质上,客户端通过将该记号传回服务器,要求服务器验证其(客户端)缓存。
    304HTTP状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件。
    客户端请求一个页面A。 
    服务器返回页面A,并在给A加上一个ETag。 
    客户端展现该页面,并将页面连同ETag一起缓存。 
    客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 
    服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。

    77.数组方法

    1)join()把数组上午所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
    该方法只接收一个参数,用作分隔符的字符串,然后返回包含所有数组项的字符串,如果不给join()方法传入任何值,则使用逗号作为分隔符。

    var a = [1,2,3];
    console.log(a.join());//'1,2,3'
    console.log(a.join(' '));//'1 2 3'
    console.log(a.join(''));//'123'
    var b = new Array(10);
    b.join('-');//'---------',9个连字符组成的字符串

    注意:如果join()方法的参数是undefined,标准浏览器以逗号为分隔符返回字符串,而IE7-浏览器以"undefined"为分隔符返回字符串;
    如果数组中某一项的值是null或者undefined,则该值在join()方法返回的结果中以空字符串表示。
    2)push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并且返回修改后数组的长度。

    var a = [];
    console.log(a,a.push(1));//[1] 1
    console.log(a,a.push('a'));//[1,'a'] 2
    console.log(a,a.push(true, {}));//[1,'a',true,{}] 4
    console.log(a,a.push([5,6]));//[1,'a',true,{},[5,6]] 5

    3)pop()方法从数组末尾移除最后一项,减少数组的length,然后返回移除的项。

    var a = ['a', 'b', 'c'];
    console.log(a,a.pop()); // ['a', 'b'] 'c'

    注意:给pop参数传其他数字不起作用,也不报错。还是只删除最后一项;
    对空数组使用pop()方法,不会报错,而是返回undefined
    4)shift()方法移除数组中的第一个项并返回该项,同时数组的长度减1

    var a = ['a', 'b', 'c'];
    console.log(a,a.shift());//['b', 'c'] 'a'
    var arr6 = [1];
    console.log(arr6,arr6.shift()); //[] 1

    注意:对空数组使用shift()方法,不会报错,而是返回undefined
    5)unshift()方法在数组前面添加任意个项并返回新数组长度。

    var a = ['a', 'b', 'c'];
    console.log(a,a.unshift('x')); //['x', 'a', 'b', 'c'] 4

    注意:当传入多个参数时,是一次性插入。最终的数组中插入的元素的顺序和它们在参数列表中的 顺序一致;
    IE-7浏览器中,unshift()方法的返回值总是undefined
    6)reserve()方法用于反转数组的顺序,返回经过排序之后的数组;而原来数组的顺序也发生改变。

    var array = [1,2,4,3,5];
    console.log(array,array.reverse());//[5,3,4,2,1] [5,3,4,2,1]
    var array = ['str',true,3];
    console.log(array,array.reverse());//[3,true,'str'] [3,true,'str']

    7)sort()按照字符编码的顺序进行排序。sort()方法会调用每个数组项的toString()方法,然后比较得到的字符串排序,返回经过排序之后的数组,而原数组顺序也发生改变。

    var array = [2,1,4,3,5];
    console.log(array,array.sort());//[1,2,3,4,5] [1,2,3,4,5]
    var array = ['3str',3,2,'2'];
    console.log(array,array.sort());//[2, "2", 3, "3str"] [2, "2", 3, "3str"]

    注意:如果数组包含undefined元素,它们会被排到数组的尾部;

    arrayObject.sort(sortby) 参数可选。规定排序顺序。必须是函数。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。
    8)concat()方法基于当前数组中的所有项创建一个新的数组,先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。所以concat()不影响原数组。

    // 如果不给concat()方法传递参数时,它只是复制当前的数组;
    var arr = [1,2,3];
    console.log(arr,arr.concat()); //[1,2,3] [1,2,3]
    
    // 如果参数是一个或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中;
    console.log(arr,arr.concat([6,7,8],[77,33,44]));
    //[1, 2, 3] [1, 2, 3, 6, 7, 8, 77, 33, 44]
    var arr1 = [4,5,6];
    console.log(arr,arr.concat(arr1)); //[1,2,3] [1,2,3,4,5,6]
    
    // 如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾。console.log(arr,arr.concat(4,5));//[1,2,3] [1,2,3,4,5]
    console.log(arr,arr.concat(4,[5,[6,7]]));
    //[1,2,3] [1, 2, 3, 4, 5, [6,7]]

    浅拷贝
    如果不提供参数,concat()方法返回当前数组的一个浅拷贝。

    // 该方法实际只复制了数组的第一维。
    // 数组第一维存放的是第二维的引用,而第二维才是实际存放他们的内容
    var numbers = [1,2];
    var newNumbers = numbers.concat();
    console.log(numbers,newNumbers);//[1,2] [1,2]
    numbers[0] = 0;
    console.log(numbers,newNumbers);//[0,2] [1,2]
    var numbers = [[1,2]];
    var newNumbers = numbers.concat();
    console.log(numbers,newNumbers);//[[1,2]] [[1,2]]
    numbers[0][0] = 0;
    console.log(numbers,newNumbers);//[[0,2]] [[0,2]]

    9)slice()方法基于当前数组中的一个或多个项创建一个新数组,接受一个或两个参数,最后返回新数组,所以slice()不影响原数组。
    slice(start,end)方法需要两个参数startend,返回这个数组从start位置到end位置(不包含)的一个子数组,左闭右开。
    注意:a.如果endundefined或不存在,则返回从start位置到数组结尾的所有项;
    b.如果没有参数,则返回原数组,即返回当前数组的一个浅拷贝;
    10)splice()方法用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,该方法会改变原数组。
    splice()返回一个由删除元素组成的数组,或者如果没有删除元素就返回一个空数组
    splice(start,number...)的第一个参数start指定了插入或删除的起始位置,第二个参数number指定了应该从数组中删除的元素的个数,如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。
    11)indexOf(search,start)方法接收searchstart两个参数,返回search首次出现的位置,如果没有找到则返回-1start代表从start位置开始寻找。
    12)lastIndexOf(search,start)方法从右向左查找。
    接收searchstart两个参数,返回search第一次出现的位置,如果没有找到则返回-1
    13)reduce()方法需要两个参数,第一个是执行化简操作的函数,化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回化简后的值。

    var total = [0, 1, 2, 3].reduce(function(sum, value) {
      return sum + value;
    }, 0);
    // total is 6

    reduceRight()则从右到左执行对应的化简函数
    14)map()方法对数组中的每一项运行给定的函数,返回每次函数调用的结果组成的数组,
    map方法还可以接受第二个参数,表示回调函数执行时this所指向的对象。
    15)forEach()方法对数组中的每一项运行给定的函数,这个方法没有返回值。本质上和for循环迭代数组一样。如果需要有返回值,一般使用map方法。
    forEach()方法除了接受一个必须的回调函数参数,第二个参数还可以接受一个可选的上下文参数(改变回调函数里面的this指向)

    array.forEach(callback(currentValue, index, array){
        //do something
    }, this)

    16)filter()方法对数组中的每一项运行给定的函数,返回该函数会返回true的项组成的数组。该方法常用于查询符合条件的所有数组项。
    filter()方法还可以接受第二个可选的上下文参数(改变回调函数里面的this指向)

    var arr= [1,10,20,30]
    var brr = arr.filter((item)=>{
        return item>10;
    })
    //[20,30]

    17)some()方法对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。并且当且仅当数值中的所有元素调用判定函数都返回false,它才返回false
    注意:在空数组上调用some()方法会返回false

    const isBiggerThan10 = (element, index, array) => {
      return element > 10;
    }
    
    [2, 5, 8, 1, 4].some(isBiggerThan10);  
    // false
    
    [12, 5, 8, 1, 4].some(isBiggerThan10); 
    // true

    18)every()方法对数组中的每一项运行给定函数,如果函数对每一项都返回true,则返回true;只要有一项返回false,则返回false
    19)fill()方法,用一个固定值填充一个数组中起始索引到终止索引内的全部元素

    arr.fill(value, start, end)
    var numbers = [1, 2, 3]
    numbers.fill(1);
    // results in [1, 1, 1]

    20)find()方法返回数组中满足提供的测试函数的第一个元素的值

        function isBigEnough(element) {
        return element >= 15;
        }
        [12, 5, 8, 130, 44].find(isBigEnough); // 130

    21)findIndex()方法返回数组中满足提供的测试函数的一个元素的索引

    function isBigEnough(element) {
      return element >= 15;
    }
    [12, 5, 8, 130, 44].findIndex(isBigEnough); 
    //'3'

    22)includes()方法用来判断一个数组是否包含一个指定的值,如果是,则返回true,如果没有则返回false

    let a = [1, 2, 3];
    a.includes(2); 
    // true 
    a.includes(4); 
    // false

    23)toLocaleString()方法返回一个字符串表示数组中的元素。数组中的元素将使用各自的toLocaleString方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号",")隔开

    var number = 1337;
    var date = new Date();
    var myArr = [number, date, "foo"];
    var str = myArr.toLocaleString(); 
    console.log(str); 
    // 输出 "1,337,2019/2/15 下午8:32:24,foo"

    24)copyWithin(target,start,end)方法浅复制数组的一部分到同一数组的另一个位置
    25)Array.isArray()方法用于确定传递的值是否是一个Array

        Array.isArray([]) => true;
        Array.isArray({}) => false;

    26)Array.of()

    Array.of(7);       // [7] 
    Array.of(1, 2, 3); // [1, 2, 3]
    
    Array(7);          // [ , , , , , , ]
    Array(1, 2, 3);    // [1, 2, 3]

    27)Array.from()
    对伪数组或可迭代对象(包括arguments Array,Map,Set,String…)转换成数组对象
    语法 Array.from(arrayLike, mapFn, thisArg)

    arrayLike 
    想要转换成数组的伪数组对象或可迭代对象。

    mapFn (可选参数) 
    如果指定了该参数,新数组中的每个元素会执行该回调函数。

    thisArg (可选参数) 
    可选参数,执行回调函数 mapFn 时 this 对象。

    返回值 
    一个新的数组实例

  • 相关阅读:
    c++ 与 c 的区别
    c++ 查看程序运行时间
    串口阻塞与非阻塞
    串口缓冲区
    马拉车算法
    printf 自加自减
    stack
    长度问题
    PCIE的内存地址空间、I/O地址空间和配置地址空间
    数组和指针
  • 原文地址:https://www.cnblogs.com/aisiqi-love/p/10411394.html
Copyright © 2011-2022 走看看