• 前端面试(较上一版本有更新)


    一、HTML/CSS

    1、什么是盒子模型?

    一个空间由几部分组成:边框、内边距、外边距、内容。

    IE 盒子模型:包括 marginborderpaddingcontentcontent 部分包含了 border pading

    标准 W3C 盒子模型:包括 marginborderpaddingcontentcontent 部分不包含其他 

    2、行内元素有哪些 ?块级元素有哪些?空元素有哪些?

    行内元素:abspanimginputstrongselectlabelembuttontextarea

    块级元素:divulliph1h2h3h4h5h6

    空元素:inputimgbrhrmetalink

    3、HTML5新特性,语义化

    简洁的DOCTYPE<!DOCTYPE html>

    简单易记的编码类型:<meta charset=utf-8/>

    脚本和链接无需type

    <link rel="stylesheet" href="path/to/stylesheet.css" />

    <script src="path/to/script.js"></script>

    语义化新增标签:<article><section><aside><hgroup><header>,<footer><nav><time><mark><figure> <figcaption>

    4、什么是优雅降级和渐进增强?

    优雅降级:开始构建完整的项目,后期针对低版本浏览器进行兼容;

    渐进增强:针对低版本浏览器构建页面,保证最基本功能,然后针对高级浏览器进行效果、交互等改进和追加功能达到更好的体验。

    5 display属性和 visibility属性的区别?

    Displayinlin-block像内联元素一样显示,none不显示不占空间,block像块级元素一样显示;

    Visibility:hidden;仅仅是视觉上透明不显示,空间位置占据

    6CSSlink @import的区别是?

    (1) link属于HTML标签,而@importCSS提供的;

    (2) 页面被加载的时,link会同时被加载,而@import被引用的CSS会等到引用它的CSS文件被加载完再加载;

    (3) import只在IE5以上才能识别,而linkHTML标签,无兼容问题;

    (4) link方式的样式的权重 高于@import的权重.

    7box-sizing属性主要用来控制元素的盒模型的解析模式。默认值是content-box

    content-box:让元素维持W3C的标准盒模型。元素的宽度/高度由border + padding + content的宽度/高度决定,设置width/height属性指的是content部分的宽/

    border-box:让元素维持IE传统盒模型(IE6以下版本和IE6~7的怪异模式)。设置width/height属性指的是border + padding + content

    8、CSS3新特性

    增加了新的选择器:属性选择器([attribute^=value][attribute$=value][attribute*=value]

    伪类选择器:动作伪类、nth选择器等;

    Transition(过渡),

    Transform(动画2D3D)该属性允许我们对元素进行旋转、缩放、移动或倾斜等操作

    Animation(动画)

    渐变:linear-gradient(线性渐变)radial-gradient(径向渐变)

    9、你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?
    Ie(trident) 火狐(Gecko) 谷歌(webkitopear(Presto)

    10.前端页面有哪三层构成,分别是什么?作用是什么?
    结构层 Html 表示层 CSS 行为层 js

    11、写出几种IE6 BUG的解决方法
    双边距BUG float引起的 使用display
    像素问题 使用float引起的 使用dislpay:inline -3px
    超链接hover 点击后失效 使用正确的书写顺序 link visited hover active
    Ie z-index问题 给父级添加position:relative
    Png 透明 使用js代码 改
    Min-height 最小高度 !Important 解决
    select ie6下遮盖 使用iframe嵌套
    为什么没有办法定义1px左右的宽度容器(IE6默认的行高造成的,使用over:hidden,zoom:0.08 line-height:1px

    12css元素的垂直居中

    <1>divParent{position:relative}

    divChild{

    400px;

    height:400px;

    position:absolute;

    top:50%;

    left:50%;

    margin-left:-200px;

    margin-top:-200px;

    }

    <2>divBox{

    display:table-cell;

    Vertical:middle;

    Text-align:center;

    }

    <3>divParent{

    Width:800px;

    Height:800px;

    Display:flex;

    Justify-content:center;

    Align-items:center;

    }

    <4>divParent{

    Width:800px;

    Height:800px;

    Position:relative;

    }

    divChild{

    Width:200px;

    Height:200px;

    Position:absolute;

    Margin:auto;

    Top:0;

    Bottom:0;

    Left:0;

    Right:0;

    }

    13、右边固定宽度,左边自适应

    第一种:

    <style>
    body{
        display: flex;
    }
    .left{
        
        height: 200px;
        flex: 1;
    }
    .right{
        background-color: red;
        height: 200px;
         100px;
    }
    </style>
    <body>
        <div class="left"></div>
        <div class="right"></div>
    </body>

    第二种:

    <style>
        div {
            height: 200px;
        }
        .left {
            float: right;
             200px;
            background-color: rebeccapurple;
        }
        .right {
            margin-right: 200px;
            background-color: red;
        }
    </style>
    <body>
        <div class="left"></div>
        <div class="right"></div>
    </body>

    14关于清除浮动的四种方法

    overflow:hidden; .clear{clear:both;};父级div定 height

    15flex弹性布局?(多次)

    FlexFlexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

    注:设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

    分为容器和容器成员:容器的属性(6个)

    flex-direction:决定主轴方向(水平左(默认)、水平右、垂直上、垂直下)

    flex-wrap:决定换行方式(不换行、第一行在上、第二行在上)

    flex-flow

    justify-content:项目在主轴上的对齐方式

    align-items

    align-content

    14rem布局原理

    原理是,先按定高宽设计出来页面,然后转换为rem单位,配合js查询屏幕大小来改变htmlfont-size,最终做出所谓的完美自适应。


    二、javascript

    1js的基本类型有哪些?引用类型有哪些?nullundefined的区别。

    基本类型就是UndefinedNullBooleanNumberString;

    引用类型是object;

    undefined表示变量声明但未初始化时的值,

    null表示准备用来保存对象,还没有真正保存对象的值。从逻辑角度看,null值表示一个空对象指针。
    2如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

    Object.prototype.toString

    function isArrayFn (o) { 
    return Object.prototype.toString.call(o) .slice(8,-1)=== '[object Array]'; 

    var arr = [1,2,3,1]; 
    alert(isArrayFn(arr));// true 

    Array.isArray() 

    最佳:

    var arr = [1,2,3,1]; 
    var arr2 = [{ abac : 1, abc : 2 }]; 
    function isArrayFn(value){ 
    if (typeof Array.isArray === "function") { 
    return Array.isArray(value); 
    }else{ 
    return Object.prototype.toString.call(value) === "[object Array]"; 


    alert(isArrayFn(arr));// true 
    alert(isArrayFn(arr2));// true 

    3DOM操作——怎样添加、移除、移动、复制、创建和查找节点。

    1)创建新节点

          createDocumentFragment()    //创建一个DOM片段

          createElement()   //创建一个具体的元素

          createTextNode()   //创建一个文本节点

    2)添加、移除、替换、插入

          appendChild()

          removeChild()

          replaceChild()

          insertBefore() //并没有insertAfter()

    3)查找

          getElementsByTagName()    //通过标签名称

          getElementsByName()    //通过元素的Name属性的值(IE容错能力较强,

          会得到一个数组,其中包括id等于name值的)

          getElementById()    //通过元素Id,唯一性

    4、创建ajax的过程

        (1)创建`XMLHttpRequest`对象,也就是创建一个异步调用对象.

        (2)创建一个新的`HTTP`请求,并指定该`HTTP`请求的方法、`URL`及验证信息.

    (3)设置响应`HTTP`请求状态变化的函数.

        (4)发送`HTTP`请求.

        (5)获取异步调用返回的数据.

        (6)使用JavaScriptDOM实现局部刷新.

    function loadShow(){

    Var xmlHttp;

    If(window.MXLHTTPRequest){

    xmlHttp=new XMLHTTPRequest();

    }else{

    xmlHttp=new ActiveXObject(“Microsoft.XMLHTTP”)

    };

    xmlHttp.onreadystatechange=function(){

    If(xmlHttp.readyState===4&&xmlHttp.status===200){

    Document.getElementById(“ID”).innerHTML=xmlHttp.responseText

    }

    };

    xmlHttp.open(‘GET’,’demo.php’,true);

    xmlHttp.send()

    }

    $.ajax({

    Url:”请求地址”,

    dataType:”xml jsonp json text html script”,//数据类型

    Anysnc:”true”,//是否异步

    Data:{‘’:’’},

    Type:”GET”,//请求格式

    Beforesendfunction(){},

    Success:function(){},

    Completefunction(){},

    Error:function(){}

    })

    5ajax的缺点

      1ajax不支持浏览器back按钮。

      2)安全问题 AJAX暴露了与服务器交互的细节。

      3)对搜索引擎的支持比较弱。

      4)破坏了程序的异常机制。

      5)不容易调试。

    6GETPOST的区别,何时使用POST

       GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符

       POST:一般用于修改服务器上的资源,对所发送的信息没有限制。

       GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。

    然而,在以下情况中,请使用 POST 请求:

    无法使用缓存文件(更新服务器上的文件或数据库)

    向服务器发送大量数据(POST 没有数据量限制)

    发送包含未知字符的用户输入时,POST GET 更稳定也更可靠

    7HTTP状态码:

        100  Continue  继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息

        200  OK   正常返回信息

        201  Created  请求成功并且服务器创建了新的资源

        202  Accepted  服务器已接受请求,但尚未处理

        301  Moved Permanently  请求的网页已永久移动到新位置。

        302 Found  临时性重定向。

        303 See Other  临时性重定向,且总是使用 GET 请求新的 URI

        304  Not Modified  自从上次请求后,请求的网页未修改过。

        400 Bad Request  服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。

        401 Unauthorized  请求未授权。

        403 Forbidden  禁止访问。

        404 Not Found  找不到如何与 URI 相匹配的资源。

        500 Internal Server Error  最常见的服务器端错误。

    503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

    8javascript继承的优缺点:

    1)原型链继承:字面量重写原型会中断关系,子类型无法给超类型传参

    2)借用构造函数继承:可以传参,但没有原型,无法复用

    3)组合继承(原型链和构造函数)

    原型链继承:(利用原型让一个引用类型继承另外一个引用类型的属性和方法)

    function SuperType() {

    this.property = true;

    }

    SuperType.prototype.getSuperValue = function() {

    return this.property;

    }

    function subType() {

    this.property = false;

    }

    //继承了SuperType

    SubType.prototype = new SuperType();

    SubType.prototype.getSubValue = function (){

    return this.property;

    }

    var instance = new SubType();

    console.log(instance.getSuperValue());//true

    借用构造函数:(在子类型构造函数的内部调用超类构造函数,通过使用call()apply()方法可以在新创建的对象上执行构造函数)

    function SuperType() {

    this.colors = ["red","blue","green"];

    }

    function SubType() {

    SuperType.call(this);//继承了SuperType

    }

    var instance1 = new SubType();

    instance1.colors.push("black");

    console.log(instance1.colors);//"red","blue","green","black"

    var instance2 = new SubType();

    console.log(instance2.colors);//"red","blue","green"

    组合继承:(将原型链和借用构造函数的技术组合在一块,从而发挥两者之长的一种继承模式)

    function SuperType(name) {

    this.name = name;

    this.colors = ["red","blue","green"];

    }

    SuperType.prototype.sayName = function() {

    console.log(this.name);

    }

    function SubType(name, age) {

    SuperType.call(this,name);//继承属性

    this.age = age;

    }

    //继承方法

    SubType.prototype = new SuperType();

    Subtype.prototype.constructor = Subtype;

    Subtype.prototype.sayAge = function() {

    console.log(this.age);

    }

    var instance1 = new SubType("EvanChen",18);

    instance1.colors.push("black");

    consol.log(instance1.colors);//"red","blue","green","black"

    instance1.sayName();//"EvanChen"

    instance1.sayAge();//18

    var instance2 = new SubType("EvanChen666",20);

    console.log(instance2.colors);//"red","blue","green"

    instance2.sayName();//"EvanChen666"

    instance2.sayAge();//20

    原型式继承:(借助原型可以基于已有的对象创建新对象,同时还不必须因此创建自定义的类型)

    var person = {

    name:"EvanChen",

    friends:["Shelby","Court","Van"];

    };

    var anotherPerson = object(person);

    anotherPerson.name = "Greg";

    anotherPerson.friends.push("Rob");

    var yetAnotherPerson = object(person);

    yetAnotherPerson.name = "Linda";

    yetAnotherPerson.friends.push("Barbie");

    console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"

    寄生式继承:(创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真正是它做了所有工作一样返回对象)

    function createAnother(original) {

    var clone = object(original);

    clone.sayHi = function () {

    alert("hi");

    };

    return clone;

    }

    var person = {

    name:"EvanChen",

    friends:["Shelby","Court","Van"];

    };

    var anotherPerson = createAnother(person);

    anotherPerson.sayHi();///"hi"

    寄生组合式继承(通过借用函数来继承属性,通过原型链的混成形式来继承方法)

    function SuperType(name){

    this.name = name;

    this.colors = ["red","blue","green"];

    }

    SuperType.prototype.sayName = function (){

    alert(this.name);

    };

    function SubType(name,age){

    SuperType.call(this,name);

    this.age = age;

    }

    inheritProperty(SubType,SuperType);

    SubType.prototype.sayAge = function() {

    alert(this.age);

    }

    9、简述一次完整的HTTP请求是怎样一个过程?

    1)域名解析:解析域名为对应的ip地址(首先浏览器自身DNS缓存,没有则会针对系统DNS缓存,再没有则尝试读取hosts文件)

    2)发起tcp3次握手(获得ip地址后,浏览器会以一个随机端口向服务器的web程序发起tcp请求链接)

    3)建立tcp连接后发起http请求

    4)服务器端响应HTTp请求,浏览器得到html代码

    5)浏览器解析HTML代码,渲染呈现给用户

    10、把接收的json数据转换成json字符

    obj.toJSONString(); //JSON对象转化为JSON字符

    JSON.stringify(obj); //JSON对象转化为JSON字符

    11创建对象的多种方式

    第一种:用Object构造函数

      var a = new Object();

      var b = new Object();

    第二种:对象字面量的方式

      var a = {};

      a.name = 'li';

    a.age = 21;

    12new 一个对象具体做了什么

    var obj  = {};

    obj.__proto__ = Base.prototype;

    Base.call(obj); 

    第一行,我们创建了一个空对象obj
    第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
    第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”,关于call函数的用法。

    13javascript闭包

    function f1(){

        var n=999;

        function f2(){
           alert(n); // 999
         }

      }

    概念:内部受保护的函数就是闭包;(闭包就是能够读取其他函数内部变量的函数。

    由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数”。所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

    闭包的用途:一个是前面提到的可以读取函数内部的变量,是让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。

    使用闭包的注意点

    1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    14、变量提升变量提升即将变量声明提升到它所在作用域的最开始的部分。

    console.log(global); // undefined

    var global = 'global';

    console.log(global); // global

    function fn () {

      console.log(a); // undefined

      var a = 'aaa';

      console.log(a); // aaa

    }

    fn();

    本质代码如下:

    var global; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值

    console.log(global); // undefined

    global = 'global'; // 此时才赋值

    console.log(global); // 打印出global

    function fn () {

      var a; // 变量提升,函数作用域范围内

      console.log(a);

      a = 'aaa';

      console.log(a);

    }

    fn();

    15函数提升

    js中创建函数有两种方式:函数声明式和函数字面量式。只有函数声明才存在函数提升!

    console.log(f1); // function f1() {}   

    console.log(f2); // undefined  

    function f1() {}

    var f2 = function() {}

    执行如下:

    function f1() {} // 函数提升,整个代码块提升到文件的最开始<br>     console.log(f1);   

    console.log(f2);   

    var f2 = function() {}

    16常用的字符串函数

    concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串。

    indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1

    charAt() – 返回指定位置的字符。

    lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1

    match() – 检查一个字符串是否匹配一个正则表达式。

    substr() 函数 -- 返回从stringstartPos位置,长度为length的字符串

    substring() – 返回字符串的一个子串。传入参数是起始位置和结束位置。

    slice() – 提取字符串的一部分,并返回一个新字符串。

    replace() – 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。

    search() – 执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值。否则返回 -1

    split() – 通过将字符串划分成子串,将一个字符串做成一个字符串数组。

    length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。

    toLowerCase() – 将整个字符串转成小写字母。

    toUpperCase() – 将整个字符串转成大写字母。

    17、常用的数组函数

    concat() 连接两个或更多的数组,并返回结果。

    join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。

    pop() 删除并返回数组的最后一个元素。  

    shift() 删除并返回数组的第一个元素

    push() 向数组的末尾添加一个或更多元素,并返回新的长度。

    unshift() 向数组的开头添加一个或更多元素,并返回新的长度。

    reverse() 颠倒数组中元素的顺序。

    slice() 从某个已有的数组返回选定的元素

    sort() 对数组的元素进行排序

    splice() 删除元素,并向数组添加新元素。

    toSource() 返回该对象的源代码。

    toString() 把数组转换为字符串,并返回结果。

    toLocaleString() 把数组转换为本地数组,并返回结果。

    valueOf() 返回数组对象的原始值

    18jQuery的事件委托方法bind livedelegateon之间有什么区别?

    <1>bind jQuery 1.3之前】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:bind(type,[data],function(eventObject))

    特点:

      (1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件。

      (2)、当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题。

    实例如下:$( "#members li a" ).bind( "click", function( e ) {} );

    <2>live jQuery 1.3之后】

    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

    语法:live(type, [data], fn);

    特点:

      (1)live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。

      (2)live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。

      (3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即$(ul").live...可以,但$("body").find("ul").live...不行; 

    实例如下:$( document ).on( "click", "#members li a", function( e ) {} );

    <3>delegate jQuery 1.4.2中引入】

    定义和用法:将监听事件绑定在就近的父级元素上

    语法:delegate(selector,type,[data],fn)

    特点:

      (1)、选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。

      (2)、更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。

    实例如下:

    $("#info_table").delegate("td","click",function(){/*显示更多信息*/});

    $("table").find("#info").delegate("td","click",function(){/*显示更多信息*/});

    <4>on 1.7版本整合了之前的三种方式的新事件绑定机制】

    定义和用法:将监听事件绑定到指定元素上。

    语法:on(type,[selector],[data],fn)

    实例如下:$("#info_table").on("click","td",function(){/*显示更多信息*/});参数的位置写法与delegate不一样。

    说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()

    .bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()

    19$(document).ready()方法和window.onload有什么区别?

     (1)window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。

     (2)$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。

    20tapclick事件的区别?

    两者都会在点击时触发,但在web移动端click会有200-300ms的延时,所以要用tap代替click作为点击事件,singleTapdoubleTap分别作为单次点击和双击,但是使用tap会带来点透事件(事件穿透)

    21、什么是跨域?跨域请求资源的方法有哪些?

    //什么是跨域?

    由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。存在跨域的情况:

    网络协议不同,如http协议访问https协议。

    端口不同,如80端口访问8080端口。

    域名不同,如qianduanblog.com访问baidu.com

    子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com

    域名和域名对应ip,www.a.com访问20.205.28.90.

    //跨域请求资源的方法:

    (1)porxy代理

    定义和用法:proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。

    实现方法:通过nginx代理;

    注意点:1、如果你代理的是https协议的请求,那么你的proxy首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。

    (2)CORS Cross-Origin Resource Sharing

    定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。

    使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:

    res.writeHead(200, {

        "Content-Type": "text/html; charset=UTF-8",

        "Access-Control-Allow-Origin":'http://localhost',

        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',

        'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type'

    });

    (3)jsonp

    定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。

    特点:通过情况下,通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。

    实例如下:

    <script>

        function testjsonp(data) {

           console.log(data.name); // 获取返回的结果    }</script>

    <script>

        var _script = document.createElement('script');

        _script.type = "text/javascript";

        _script.src = "http://localhost:8888/jsonp?callback=testjsonp";

        document.head.appendChild(_script);</script>

    缺点:

    1、这种方式无法发送post请求(这里)

    2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

    22、判断一个字符串中出现次数最多的字符,统计这个次数

    var str = 'asdfssaaasasasasaa';var json = {};for (var i = 0; i < str.length; i++) {

        if(!json[str.charAt(i)]){

           json[str.charAt(i)] = 1;

        }else{

           json[str.charAt(i)]++;

        }

    };var iMax = 0;var iIndex = '';for(var i in json){

        if(json[i]>iMax){

             iMax = json[i];

             iIndex = i;

        }

    }        

    console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'');

    23、如何获取浏览器URL查询字符串中的参数

    function showWindowHref(){

        var sHref = window.location.href;

        var args = sHref.split('?');

        if(args[0] == sHref){

            return "";

        }

        var arr = args[1].split('&');

        var obj = {};

        for(var i = 0;i< arr.length;i++){

            var arg = arr[i].split('=');

            obj[arg[0]] = arg[1];

        }

        return obj;

    }

    var href = showWindowHref(); // obj

    console.log(href['name']); // xiaoming

    24、数组去重的常用方法

     //遍历数组法

    Function unique1(array){

    Var str1=[];

    For(var i=0;i<array.length;i++){

    If(str1.indexOf(array[i])==-1){

    Str1.push(array[i])

    }

    }

    Return str1;

    }

    //先排序相邻去除法

    Function unique2(array){

    Array.sort();

    Var str2=[array[0]];

    For(var i=0;i<array.length;i++){

    If(array[i]!==str2[str2.length-1]){

    Str2.push(array[i])

    }

    }

    Return str2;

    }

    //对象键值对法

    Function unique3(array){

    Var obj={},str3=[];

    For(var i=0;i<array.length;i++){

    If(!obj[array[i]]){

    Str3.push(array[i]);

    Obj[array[i]]=1;

    }

    }

    Return str3;

    }

    25、克隆函数

    Function clone(obj){

    Var o;

    Switch(typeOf obj){

    Case “undefined”:

    Break;

    Case “string”:o=obj+””;

    Break;

    Case “number”:o=obj-0;

    Break;

    Case “boolean”:o=obj;

    Break;

            Case “object”:

    If(obj===null){

    o=null;

    }else {

    If(Object.prototype.toString.call(obj).slice(8,-1)===”Array”){

    O=[];

    For(var i=0;i<obj.length;i++){

    O.push(clone(obj[i]))

    }

    }else{

    O={};

    For(var key in obj){

    O[key]=clone(obj[key])

    }

    }

    }

    Break;

    Default :o=obj;

     Break;

    }

    Return o;

    }

    26、排序算法

    //1、冒泡排序
    function subSort(arr1){
        for(var i=0;i<arr1.length;i++){
            for(var j=0;j<arr1.length-1-i;j++){
                if(arr1[j]>arr1[j+1]){//相邻元素对比
                    var temp=arr1[j+1];
                    arr1[j+1]=arr1[j];
                    arr1[j]=temp;
                }
            }
        }
        return arr1;
    }
    var arr1=[3,5,9,8,11,55,22,44,12,23]
    console.log(subSort(arr1))

    //2.选择排序
    function selectionSort(arr2){
        var temp,minIndex
        for(var i=0;i<arr2.length-1;i++){
            minIndex=i;
            for(var j=i+1;j<arr2.length;j++){
                if(arr2[j]<arr2[minIndex]){
                    minIndex=j
                }
            }
            temp=arr2[i]
            arr2[i]=arr2[minIndex]
            arr2[minIndex]=temp
        }
        return arr2
    }
    var arr2=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
    console.log(selectionSort(arr2));

    //3.插入排序
    function insertionSort(array) {
        for (var i = 1; i < array.length; i++) {
            var key = array[i];
            var j = i - 1;
            while ( array[j] > key) {
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = key;
        }
        return array;
    }
    var arr3=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
    console.log(insertionSort(arr3));

    27JavaScript两个变量交换值的实现方法

    //1.普通做法

    var a=1,b=2;

    var temp;

    temp=a

    a=b

    b=temp

    通过变量temp作为中间量,将两个变量值进行交换

    //2.算数运算

    var a = 1,b = 2;

    a = a + b; // a = 3, b = 2

    b = a - b; // a = 3, b = 1

    a = a - b;// a = 2, b = 1

    //3.ES6解构

    let a = 1,b = 2;

    [a, b] = [b, a];

    28、数字转成大写:

    function intToChinese ( str ) {

     str = str+'';

     var len = str.length-1;

     var idxs = ['','','','','','','','','亿','','','','','','','','亿'];

     var num = ['','','','','','','','','',''];

     return str.replace(/([1-9]|0+)/g,function( $, $1, idx, full) {

      var pos = 0;

      if( $1[0] != '0' ){

       pos = len-idx;

       if( idx == 0 && $1[0] == 1 && idxs[len-idx] == ''){

        return idxs[len-idx];

       }

       return num[$1[0]] + idxs[len-idx];

      } else {

       var left = len - idx;

       var right = len - idx + $1.length;

       if( Math.floor(right/4) - Math.floor(left/4) > 0 ){

        pos = left - left%4;

       }

       if( pos ){

        return idxs[pos] + num[$1[0]];

       } else if( idx + $1.length >= len ){

        return '';

       }else {

        return num[$1[0]]

       }

      }

     });

    }

    29、回文的判断?

    function isPalindrome(line) {  

        line += "";  

        for(var i=0,j=line.length-1;i<j;i++,j--){  

            if(line.charAt(i) !== line.charAt(j)){  

                return false;  

            }  

        }  

        return true;  

    }  

    30、判断邮箱

    RegExp(/^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/)

    31、驼峰命名与连字符命名的转换

    驼峰转连字符:

    function getKebabCase ( str ) {

    var arr = str.split('');

    str = arr.map(function ( item ){

    if( item.toUpperCase() === item ){

    return '-' + item.toLowerCase();

    }else{

    return item; }

     }).join( '' );

     return str;

    }

    console.log( getKebabCase( 'getElementById' ) ); //get-element-by-id


    function getKebabCase( str ) {

    return str.replace( /[A-Z]/g, function( i ) {

    return '-' + i.toLowerCase();

    })

     }

    console.log( getKebabCase( 'getElementById' ) ); //get-element-by-id

    转驼峰

    function getCamelCase( str ) {

     var arr = str.split( '-' );

    return arr.map( function( item, index ) {

     if( index === 0 ){

     return item;

     }else{

    return item.charAt(0).toUpperCase() + item.slice( 1 ); }

    }).join('');

     }

    console.log( getCamelCase( 'get-element-by-id' ) ); //getElementById

    function getCamelCase( str ) {

    return str.replace( /-([a-z])/g,

    function( all, i ){

    return i.toUpperCase();

     } )

    }

    console.log( getCamelCase( 'get-element-by-id' ) ); //getElementById

    32、js去掉前后字符

    function trim(str){

    return str.replace(/(^s*)|(s*$)/g, "");

    }

    33、第1个人10,第2个比第1个人大2岁,依次递推,计算出第8个人多大 (递归)
    function add(n){

    var num=10;

    for(var i=1;i<n;i++){

    num=num+2;

    }

    return num;

    }

    console.log(add(8))//26

    34、实现字符串反转的方法

    var str = "abcdef";

    console.log( str.split("").reverse().join("") )//fedcba

    35js的延迟加载方式

    <1>使用setTimeout延迟方法的加载时间

    <script type="text/javascript" >

      function A(){

        $.post("/lord/login",{name:username,pwd:password},function(){

          alert("Hello");

        });

      }

      $(function (){

        setTimeout('A()', 1000); //延迟1

      })

    </script>

    <2><script>标签定义defer属性(HTML4)

    <script src="test1.js" defer="defer"></script>

    <3><script>标签定义 async属性(HTML5)

    <script src="test2.js" async></script>

    <4>js最后加载

    js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度

    <5>使用jQuerygetScript()方法

    $.getScript("outer.js",function(){//回调函数,成功获取文件后执行的函数  

          console.log("脚本加载完成")  

    });

    36、JavaScript常见的内置对象

    Object,Math,String,Array,Number,Function,Boolean,JSON

    37、JS的事件冒泡和事件捕获

    事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。相反的,事件冒泡是自下而上的去触发事件。绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获。true,事件捕获;false,事件冒泡。默认false,即事件冒泡。Jquerye.stopPropagation会阻止冒泡,意思就是到我为止,我的爹和祖宗的事件就不要触发了。

    <div id="parent">

      <div id="child" class="child"></div>

    </div>

    document.getElementById("parent").addEventListener("click",function(e){

                    alert("parent事件被触发,"+this.id);

                })          document.getElementById("child").addEventListener("click",function(e){

                    alert("child事件被触发,"+this.id)

                })

    结果:child,然后parent。事件的触发顺序自内向外,这就是事件冒泡。

    child事件被触发,child

    parent事件被触发,parent

    现在改变第三个参数的值为true意思为事件捕获

    结果:parent,然后child。事件触发顺序变更为自外向内,这就是事件捕获。

    parent事件被触发,parent

    child事件被触发,child

     

    三、VUE框架部分

    1、v-show指令和v-if指令的区别?

    条件渲染指令,与v-if不同的是,无论v-show的值为true或者false,元素都会存在于HTML代码中,而v-if只有在为true时才会在HTML代码中存在,v-show设置cssstyle

    2、<style scoped></style>css代码只在当前组件起作用

    3、指令keep-alive含义:在vue-router中写keep-alive保留状态,避免重新渲染

    4、Vue.js特点:

    简洁:页面由HTML模板+Json数据+Vue实例组成 

    数据驱动:自动计算属性和追踪依赖的模板表达式

    组件化:用可复用、解耦的组件来构造页面

    轻量:代码量小,不依赖其他库

    快速:精确有效批量DOM更新 

    模板友好:可通过npmbower等多种方式安装,很容易融入

    5、vue的常用指令有哪些?

    v-ifv-showv-elsev-forv-bindv-onv-model

    8vuex核心概念?

    state => 基本数据 
    getters => 从基本数据派生的数据 
    mutations => 提交更改数据的方法,同步! 
    actions => 像一个装饰器,包裹mutations,使之可以异步。 
    modules => 模块化Vuex

    10、怎么定义vue-router的动态路由?怎么获取传过来的动态参数?

    答:在router目录下的index.js文件中,对path属性加上/:id。  使用router对象的params.id

    11vue-router有哪几种导航钩子?

    第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。

    第二种:组件内的钩子;

    第三种:单独路由独享组件

    12mint-ui是什么?怎么使用?说出至少三个组件使用方法?

    答:基于vue的前端组件库。npm安装,然后import样式和js

    vue.usemintUi)全局引入。在单个组件局部引入:import {Toast} from mint-ui’。

    组件一:Toast(‘登录成功’)

    组件二:mint-header

    组件三:mint-swiper

    13axios是什么?怎么使用?描述使用它实现登录功能的流程?

    答:请求后台资源的模块。npm install axios -S装好,

    然后发送的是跨域,需在配置文件中config/index.js进行设置。

    后台如果是Tp5则定义一个资源路由。js中使用import进来,

    然后.get.post。返回在.then函数中如果成功,

    失败则是在.catch函数中

    14vuex是什么?怎么使用?哪种功能场景使用它?

    答:vue框架中状态管理。在main.js引入store,注入。

    新建了一个目录store,….. export

    场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车

    15mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?

    答:一个model+view+viewModel框架,数据模型modelviewModel连接两个

    区别:vue数据驱动,通过数据来显示视图层而不是节点操作。

    场景:数据操作比较多的场景,更加便捷

    16、自定义指令(v-checkv-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?

    答:全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数。组件内定义指令:directives钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)update(组件内相关更新)钩子函数参数:elbinding

    17、说出至少4vue当中的指令和它的用法?

    答:v-if:判断是否隐藏;v-for:数据循环出来;v-bind:class:绑定一个属性;v-model:实现双向绑定

    18Vue的双向数据绑定原理是什么?

    答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应的监听回调。

    具体步骤:

    第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 settergetter

    这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化

    第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

    第三步:Watcher订阅者是ObserverCompile之间通信的桥梁,主要做的事情是:1、在自身实例化时往属性订阅器(dep)里面添加自己2、自身必须有一个update()方法3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。

    第四步:MVVM作为数据绑定的入口,整合ObserverCompileWatcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起ObserverCompile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

    19、请详细说下你对vue生命周期的理解?

    答:总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

    创建前/后: 在beforeCreated阶段,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,$el还没有。

    载入前/后:在beforeMount阶段,vue实例的$eldata都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

    更新前/后:当data变化时,会触发beforeUpdateupdated方法。

    销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

    20、请说下封装 vue 组件的过程?

    答:首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。

    然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。

    21vue-loader是什么?使用它的用途有哪些?

    答:解析.vue文件的一个加载器,跟template/js/style转换成js模块。

    用途:js可以写es6style样式可以scsslesstemplate可以加jade

    22、请说出vue.cli项目中src目录每个文件夹和文件的用法?

    答:assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件

    23、聊聊你对Vue.jstemplate编译的理解?

    答:简而言之,就是先转化成AST树,再得到的render函数返回VNodeVue的虚拟DOM节点)

    详情步骤:

    首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compilecreateCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option

    然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNodeVNodeVue的虚拟DOM节点,里面有(标签名、子节点、文本等等)

    24vue的组件是怎么定义的?父组件怎么给子组件传值?

    答:首先注册vue.components,第一个参数是组件名称,第二个参数是选项。

    直接绑定一个属性,然后在子组件props里面接收

    27、说下你对mvvm的理解?双向绑定的理解?

    答:mvvm就是vm框架视图、m模型就是用来定义驱动的数据、v经过数据改变后的htmlvm就是用来实现双向绑定

        双向绑定:一个变了另外一个跟着变了,例如:视图一个绑定了模型的节点有变化,模型对应的值会跟着变

    25、请说下具体使用vue的理解?

    1、使用vue不必担心布局更改和类名重复导致的js重写,因为它是靠数据驱动双向绑定,底层是通过Object.defineProperty() 定义的数据 setget 函数原理实现。2、组件化开发,让项目的可拓展性、移植性更好,代码重用性更高,就好像农民工建房子,拿起自己的工具包就可以开工。项目经理坐等收楼就好。3、单页应用的体验零距离接触安卓原生应用,局部组件更新界面,让用户体验更快速省时。4js的代码无形的规范,团队合作开发代码可阅读性更高。

    26、你觉得哪些项目适合vue框架?

    答:1、数据信息量比较多的,反之类似企业网站就无需此框架了。2、手机webapp应用多端共用一套界面的项目,因为使用vue.cli+webpack后的前端目录,非常有利于项目的跨平台部署。

    27、怎么理解MVVM模式的这些框架?

    答:1M就是Model模型层,存的一个数据对象。2V就是View视图层,所有的html节点在这一层。3VM就是ViewModel,它通过data属性连接Model模型层,通过el属性连接View视图层。
    28vuex有哪几种属性?

    答:有五种,分别是 StateGetterMutation Action Module

    29vuexState特性是?

    一、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data

    二、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新

    三、它通过mapState把全局的 state getters 映射到当前组件的 computed 计算属性中

    30vuexGetter特性是?

    一、getters 可以对State进行计算操作,它就是Store的计算属性

    二、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用

    三、 如果一个状态只在一个组件内使用,是可以不用getters

    31vuexMutation特性是?

    一、Action 类似于 mutation,不同在于:

    二、Action 提交的是 mutation,而不是直接变更状态。

    三、Action 可以包含任意异步操作

    32Vue.jsajax请求代码应该写在组件的methods中还是vuexactions中?

    1>如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex state里。

    2>如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。

    33、不用Vuex会带来什么问题?

    一、可维护性会下降,你要想修改数据,你得维护三个地方

    二、可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的

    三、增加耦合,大量的上传派发,会让耦合性大大的增加,本来VueComponent就是为了减少耦合,现在这么用,和组件化的初衷相背。

    34、第一次页面加载会触发哪几个钩子?

    答:第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

    35、简单描述每个周期具体适合哪些场景?

    答:生命周期钩子的一些使用方法: beforecreate : 可以在这加个loading事件,在加载实例时触发 created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用 mounted : 挂载元素,获取到DOM节点 updated : 如果对数据统一处理,在这里写上相应函数 beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom
    36axios的特点有哪些?

    1>Axios 是一个基于 promise HTTP 库,支持promise所有的API

    2>、它可以拦截请求和响应

    3>、它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据

    4>、安全性更高,客户端支持防御 XSRF

    37axios有哪些常用方法?

    一、axios.get(url[, config])   //get请求用于列表和信息查询

    二、axios.delete(url[, config])  //删除

    三、axios.post(url[, data[, config]])  //post请求用于信息的添加

    四、axios.put(url[, data[, config]])  //更新操作

  • 相关阅读:
    编程实现SQL Server备份和还原
    [推荐]asp.net string与color互换
    ASP.NET执行SQL超时的解决方案
    Starling 环形进度条实现
    [转]列举好游戏应具备的10个要素
    基于Starling的mask实现
    一直以来最头痛的问题:怎么样才能行之有效的解决游戏中后期枯燥的问题呢?求解
    [转]战棋系统的分析
    [转] java开源游戏
    设计模式(基础篇)软件设计七大设计原则(续一)
  • 原文地址:https://www.cnblogs.com/wangpengfei8313/p/8690910.html
Copyright © 2020-2023  润新知