美文网首页
前端面试题实战1

前端面试题实战1

作者: 我家媳妇蠢蠢哒 | 来源:发表于2019-04-25 10:47 被阅读0次

    前端面试题汇总

    1、函数的创建方式有哪几种?举一个闭包的的例子,举一个曾经封装过的函数,简单阐述一下原型链的使用,谈谈你对this的理解

    答:三种,分别是:函数声明、函数表达式、函数对象方式

    第一种(函数声明)

    function sum1 (n1, n2){

    return n1 + n2;

    }

    第二种(函数表达式)

    var sum2 = function (n1, n2){

    Return n1 + n2;

    }

    第三种(函数对象方式)

    var sum3 = new Function (‘n1’ , ‘n2’, ‘return n1 + n2’)

    闭包就是能够读取其他函数内部变量的函数,本质上闭包就是函数内部和函数外部架起来的一架桥梁。

    function outer(){

    var num1 = 2;

    function inner(){

    Var num2 = 1;

    alert (num1 + num2);

    }

    return inner;

    }

    Outer()()

    原型链的使用:当我们创建一个新函数的时,都会自动为函数创建一个prototype的属性,这个prototype属性是一个指针指向了这个函数的原型对象,而这个原型对象会自动创建一个constructor的属性,constructor属性也是一个指针,指向prototype属性所在的那个函数。

    this的理解:

    作为对象方法调用,这个时候的this指向该对象

    var obj = {

    a:1,

    getA:function (){

    alert(this===obj);//true

    alert(this.a);//1

    }

    }

    作为普通函数调用,这个时候this总是指向全局对象(在浏览器中既window对象)

    window.name='zhangshan';

    var getName=function(){

    console.log(this.name);//zhangshan

    }

    作为构造器调用,这个时候this的指向就分情况了,主要是看构造器有没有显式返回一个对象。

    当用new 运算符调用函数时,该函数总会返回一个对象,通常情况this就是指向这个对象的

    但是如果构造器显式的返回一个object类的对象,那么运算结果最终返回的事那个对象而不是this,所以这个时候this指向的对象就是显式返回的那个对象

    var MyClass1 = function(){

        this.name = '111';

    }var obj1 = new MyClass1();

    alert(obj1.name); //111

    var MyClass2 = function(){

        this.name = '111';

        return { //显式的返回一个对象

            name: '222';

        }

    }var obj2 = new MyClass2();

    alert(obj2.name); //222

    2、浏览器渲染页面的过程

    答:浏览器会把HTML、SVG、XHTML三种格式的文件会产生一个DOM树;

    Css,解析css会产生css规则树

    JavaScript会通过DOM apI 来操作DOM树 和 css规则树

    3、简单描述下同步和异步的区别,并举例实际应用中哪些是同步,哪些是异步?

    答:同步是阻塞的,浏览器向服务器发送请求,服务器比较忙,浏览器一直等着(页面白屏),直到服务器返回数据,页面才可以正常显示;

    异步是非阻塞的,浏览器向服务器请求数据,服务器比较忙,浏览器可以干自己原来的事情(显示页面),服务器返回数据的时候通知浏览器一声,浏览器把返回的数据再渲染到页面,局部更新。

    4、举一下jquery中的函数,这些函数实现链式编程的原理?

    答:toggle(fn, fn)

    $(“td”).toggle(

    function(){

    $(this).addClass(“selected”);

    },

    function(){

    $(this).removeClass(“selected”);

    实现函数链式编程的原理:返回自身,其他过程在函数内部实现,其好处是:节约js代码,返回的是同一个对象,提高代码的效率。

    5、webpack是怎样配置的,简要描述一下过程

    答:第一在项目文件创建一个webpack.config.js文件,配置文件创建好了,第二开始正式配置webpack了,首先下载好node.js,因为webpack基于node.js,装好node.js后,通过命令行窗口找到项目文件,在项目文件webpack.config.js文件所在的目录下输入 npm install webpack -save dev  下载webpack依赖文件到本地项目中,下载好后会在webpack.config.js文件下自动创建node_modules文件夹,文件夹里就是所有项目中用到的依赖插件,现在只有一个webpack,项目中用到在下载!

    6、npm有哪些常用的命令,请列举并说明作用

    答:$npm init                项目初始化

    $npm install -g <name>    安装并更新package.json中的版本配置

    $npm run <name>        执行一段脚本

    $npm update -n <name>  更新模块

    7、git的作用是什么,有哪些命令,这些命令的作用是什么?在pull时,如果只想要文件的一部分而不是工程文件的整个,使用什么命令?git的冲突如何解决?

    答:git是一个开源的分布式版本控制系统,用以有效、高速处理很小到非常大的项目版本管理。

    常用的命令:  git init  初始化仓库

    git config --global user.name    配置用户名

    git config --global user.email    配置邮箱

    git add      文件添加到暂存区

    git commit  文件添加到仓库

    git branch    列出所有的分支

    git status    显示有变更的文件

    git log      查看当前分支的版本历史

    git push      提交本地代码到远程

    git pull      从远程仓库下载到本地

    git checkout  创建切换分支

    解决git分支冲突:  将本地dev删除,在重新checkout一个dev分支(保证了此时我们的本地dev分支是最新的),在进行pull服务器分支,就这样解决了.

    下载一个文件不是整个文件的解决方法:当pull的时候,后面直接带hash版本就可以下载对应的上传文件版本。

    8、简述一些vue项目中文件构成?

    答:build文件夹:主要就是webpack的配置;

    Config文件夹:主要的就是index.js 这个文件进行配置代理服务器

    Src文件夹:

    “assets”共用的样式和图片

    “components”业务代码存放

    “router”路由

    “APP.vue”vue 文件入口界面

    “main.js”对应App.vue创建的实例,也是入口文件,对应 webpack.base.config.js里的入口配置

    Static文件夹:静态资源

    Pack.json:scripts 里面设置命令,例如设置了dev用于调试则我们开发时输入的是npm run dev ;例如设置了build 则是输入 npm run build 用于打包;另一部分是这里可以看到我们需要的依赖包,在dependencies和devDependencies中,分别对应全局下载和局部下载的依赖包

    9、控制台中使用哪些部分调试?

    答:主要用console来进行调试

    1、console.log 用于输出普通信息

    2、console.info 用于输出提示性信息

    3、console.error用于输出错误信息

    4、console.warn用于输出警示信息

    5、console.debug用于输出调试信息

    10、简述AJAX的工作原理

    答:Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。

     XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。

    11、jsonp是如何实现前后数据交互?

    答:ajax请求受同源策略的影响,不允许进行跨域请求,而script标签的src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不在返回json格式的数据,而是返回调用某个函数的js代码,在src中进行了调用,这样就实现了跨域,其原理就是动态创建script标签,通过script标签的src属性进行调用

    12、ajax中get和post方式的区别?

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

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

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

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

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

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

    13、ajax中需要配置的参数有哪些?

    参数名 类型 描述

    url String (默认: 当前页地址) 发送请求的地址。

    type String (默认: "GET") 请求方式 ("POST" 或 "GET"), 默认为 "GET"。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。

    timeout Number 设置请求超时时间(毫秒)。此设置将覆盖全局设置。

    async Boolean (默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。

    beforeSend Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。XMLHttpRequest 对象是唯一的参数。

    function (XMLHttpRequest) {

      this; // the options for this ajax request

    }

    cache Boolean (默认: true) jQuery 1.2 新功能,设置为 false 将不会从浏览器缓存中加载请求信息。

    complete Function 请求完成后回调函数 (请求成功或失败时均调用)。参数: XMLHttpRequest 对象,成功信息字符串。

    function (XMLHttpRequest, textStatus) {

      this; // the options for this ajax request

    }

    contentType String (默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。默认值适合大多数应用场合。

    data Object,

    String 发 送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 processData 选项说明以禁止此自动转换。必须为 Key/Value 格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。

    dataType String 预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息返回 responseXML 或 responseText,并作为回调函数参数传递,可用值:

    "xml": 返回 XML 文档,可用 jQuery 处理。

    "html": 返回纯文本 HTML 信息;包含 script 元素。

    "script": 返回纯文本 JavaScript 代码。不会自动缓存结果。

    "json": 返回 JSON 数据 。

    "jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。

    error Function (默认: 自动判断 (xml 或 html)) 请求失败时将调用此方法。这个方法有三个参数:XMLHttpRequest 对象,错误信息,(可能)捕获的错误对象。

    function (XMLHttpRequest, textStatus, errorThrown) {

      // 通常情况下textStatus和errorThown只有其中一个有值

      this; // the options for this ajax request

    }

    global Boolean (默认: true) 是否触发全局 AJAX 事件。设置为 false 将不会触发全局 AJAX 事件,如 ajaxStart 或 ajaxStop 。可用于控制不同的Ajax事件

    ifModified Boolean (默认: false) 仅在服务器数据改变时获取新数据。使用 HTTP 包 Last-Modified 头信息判断。

    processData Boolean (默认: true) 默认情况下,发送的数据将被转换为对象(技术上讲并非字符串) 以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

    success Function 请求成功后回调函数。这个方法有两个参数:服务器返回数据,返回状态

    function (data, textStatus) {

      // data could be xmlDoc, jsonObj, html, text, etc...

      this; // the options for this ajax request

    }

    14、 var btn = document.getElementsByTagName("button"); 

    for( var i=0; i<3; i++ ) { 

      btn[i].onclick = function() { 

      alert(i); 

    结果是什么?如果想要输出结果为0 1 2怎么解决?

    答:结果是3,输出结果0 1 2 的解决方法是把alert(i)放到点击事件的外边。

    14、移动端touch事件判断滑屏手势的方向?

    答:当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和纵坐标startY;

    当触发touchmove事件时,在获取此时手指的横坐标moveEndX和纵坐标moveEndY;最后,通过这两次获取的坐标差值来判断手指在手机屏幕上的滑动方向。

    思路:用touchmove的最后坐标减去touchstart的起始坐标,X的结果如果正数,则说明手指是从左往右划动;X的结果如果负数,则说明手指是从右往左划动;Y的结果如果正数,则说明手指是从上往下划动;Y的结果如果负数,则说明手指是从下往上划动。

    具体代码如下:

        var mybody = document.getElementsByTagName('body')[0];

        //滑动处理

        var startX, startY, moveEndX, moveEndY, X, Y; 

        mybody.addEventListener('touchstart', function(e) {

            e.preventDefault();

            startX = e.touches[0].pageX;

            startY = e.touches[0].pageY;

        });

        mybody.addEventListener('touchmove', function(e) {

            e.preventDefault();

            moveEndX = e.changedTouches[0].pageX;

            moveEndY = e.changedTouches[0].pageY;

            X = moveEndX - startX;

            Y = moveEndY - startY;

            if ( X > 0 ) {alert(‘向右’);}

            else if ( X < 0 ) {alert(‘向左’);}

            else if ( Y > 0) {alert(‘向下’);}

            else if ( Y < 0 ) { alert(‘向上’);}

            else{alert(‘没滑动’); }

        });

    15、怎么防止内存泄露?

    答:1.减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收

      2.注意程序逻辑,避免“死循环”之类的

      3.避免创建过多的对象 。

    16、$wtach监听怎么取消?

    答:watch的性能消耗挺大的,所以对于已经不需要监视的watch,记得定时取消掉。

    其实每个watch函数返回的结果就是这个watch的deregisterWatch()函数

    //在chrome的控制台上,断点得到的$watch的返回值

    function deregisterWatch() {

        arrayRemove(array, watcher);

        lastDirtyWatch = null;

    }

    所以啊,要取消watch的话,一开始将$watch的返回值保存就好啦,要取消watch的时候,在调用。

    var count=1;

    var unbingWatch=$scope.$watch('todoList',function(){

        console.log('todoList change');

        count++;

        //相当于在todoList变化了4次之后,就调用unbingWatch()取消这个watch

        //在第5次todoList改变的时候,就不会输出todoList change了。

        if(count>4){

            unbingWatch();

        }

    });

    16、怎样实现一个盒子垂直居中?

    一、 盒子没有固定的宽和高

    方案1、Transforms 变形

    这是最简单的方法,不仅能实现绝对居中同样的效果,也支持联合可变高度方式使用。内容块定义transform: translate(-50%,-50%)  必须加上

    top: 50%; left: 50%;

    方案2、在父级元素上面加上上面3句话,就可以实现子元素水平垂直居中。

    <div class="wrapper">

            我不知道我的宽度和高是多少,我要实现水平垂直居中。

    </div>

    .wrapper {

                width: 500px;

                height: 300px;

                background: orange;

                color: #fff;

                /*只需要在父元素上加这三句*/

                justify-content: center; /*子元素水平居中*/

                align-items: center; /*子元素垂直居中*/

                display: -webkit-flex;

            }

    二、盒子有固定的宽和高

    方案1、margin 负间距

    方案2、margin:auto实现绝对定位元素的居中(该方法兼容ie8以上浏览器)

    17、怎样实现三栏布局,两边宽度固定,中间自适应?

    答:圣杯布局  双飞翼布局

    <!DOCTYPE html>

      <html>

          <head>

              <meta charset="UTF-8">

              <title></title>

              <style type="text/css">

                      *{

                          margin: 0;

                          padding: 0;

                    }

                #left{

                    width: 200px;

                    height: 200px;

                    float: left;

                    background-color: red;

                }

                #right{

                    width: 150px;

                    height: 200px;

                    float: right;

                    background-color: mistyrose;

                }

                #middle{

                    height: 200px;

                    margin: 0 150px 0 200px;

                    background-color: saddlebrown;           

                    word-break: break-word;   

                }

            </style>

            </head>

        <body>

            <div id="content">

                <div id="left">我是左侧内容我是左侧内容我是左侧内容我是左侧内容我是左侧内容</div>

                <div id="right">我是右侧内容我是右侧内容我是右侧内容我是右侧内容我是右侧内容我是右侧内容</div>

                <div id="middle">我是中间内容我是中间内容我是中间内容我是中间内容我是中间内容我是中间内容我是中间内容我是中间内容我是中间内容我是中间内容</div>

            </div>

        </body>

    </html>

    18、移动端怎样适配不同尺寸的屏幕?除了用媒体查询设定范围外还有什么方式?

    答:通过js 来获取不同屏幕的宽度

    19、移动端对图片优化有哪些方式,怎么实现?

    答:懒加载,使用CSS Sprites合并为一张大图,首先从图片格式方面着手,webp(google官方网址)是谷歌推出的一种图片格式,优点在于同等画面质量下,体积比jpg、png少了25%以上,去掉无意义的修饰,使用矢量图替代位图。

    按照HTTP协议设置合理的缓存。

    详见链接 http://web.jobbole.com/81766/

    20、移动端对小图标有哪些好的处理方式?

    答:转换成字体图标

    21、对于移动端ICON怎么使用,用过SVG吗?它的优势在于?

    答:在移动端中使用字体icon,

      可缩放性(Scalability):

    基于字体的icon是与分辨率无关并能缩放到任何想要程度的技术。你的图标看起来毫不关心retina,HDPI,XHDPI等等屏幕,但渲染时会根据目标设备自动调整,你将有能力应对任何当下,未来,或大多数任意规格的设备

    尺寸(Size ):

    裁剪到正确的比例,icon font的文件的大小要比起位图小到难以置信的程度,使用icon font时,你不需要根据不同设备准备不同的图片,你的APP只需要在启动时加载一次icon font文件即可。

    可维护性(Maintainability):

    自你的icon打包进一个字体文件,在项目自始至终你仅需要维护这个单一的字体文件。

    通过管理字体文件你可以很自然的组织你的icon集合,任意的进行修改或扩展

    可推广性(Adoption):

    然而,应用这样的icon fonts可能会影响你和你同事之间的工作流程,但说服让他们采用这样的技术也非常简单,有数款免费或收费的工具帮你轻松达到目的并能看到很好的应用结果,在几乎任意(手机)移动平台、浏览器或操作系统

    灵活性(Flexibility):

    应用icon fonts技术中最有意义的一项能力是可以操纵icon fonts, 改变颜色,大小,仅仅几行代码就可以在瞬间改变外观

    可交互性(Interactivity):

    由于灵活性以及能够通过代码方便的操纵,icon fonts 是独一无二的在运行时被操纵,通过应用icon fonts技术, 你能轻松的在不同状态显示对应的不同效果,创建动画。

    SVG是矢量图形文件,可以随意改变大小,而不影响图标质量。

    可以用CSS样式来自由定义图标颜色,比如颜色/尺寸等效果。

    所有的SVG可以全部在一个文件中,节省HTTP请求 。

    使用SMIL、CSS或者是javascript可以制作充满灵性的交互动画效果。

    由于SVG也是一种XML节点的文件,所以可以使用gzip的方式把文件压缩到很小。

    22、canvas是怎样实现一个时钟的?

    答:实现代码如下:

    HTML代码:

    <!DOCTYPE html>

    <html>

    <head>

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <title>Clock</title>

        <style type="text/css">

        *{

            margin: 0;

            padding: 0;

        }

        .canvas{

            margin-left: 20px;

            margin-top: 20px;

            border: solid 1px;

        }

        </style>

    </head>

    <body onload= "main()">

    <canvas class = "canvas" id="canvasId" width = '500px' height = '400px'></canvas>

    <script type= "text/javascript" src = "Clock.js"></script>

    </body>

    </html>

    JS代码:

    var Canvas = {};

    Canvas.cxt = document.getElementById('canvasId').getContext('2d');

    Canvas.Point = function(x, y){

        this.x = x;

        this.y = y;

    };

    /*擦除canvas上的所有图形*/

    Canvas.clearCxt = function(){

        var me = this;

        var canvas = me.cxt.canvas;

          me.cxt.clearRect(0,0, canvas.offsetWidth, canvas.offsetHeight);

    };

    /*时钟*/

    Canvas.Clock = function(){

        var me = Canvas,

            c = me.cxt,

            radius = 150, /*半径*/

            scale = 20, /*刻度长度*/

            minangle = (1/30)*Math.PI, /*一分钟的弧度*/

            hourangle = (1/6)*Math.PI, /*一小时的弧度*/

            hourHandLength = radius/2, /*时针长度*/

            minHandLength = radius/3*2, /*分针长度*/

            secHandLength = radius/10*9, /*秒针长度*/

            center = new me.Point(c.canvas.width/2, c.canvas.height/2); /*圆心*/

        /*绘制圆心(表盘中心)*/

        function drawCenter(){

            c.save();

            c.translate(center.x, center.y); 

            c.fillStyle = 'black';

            c.beginPath();

            c.arc(0, 0, radius/20, 0, 2*Math.PI);

            c.closePath();

            c.fill();

            c.stroke();

            c.restore();

        };

        /*通过坐标变换绘制表盘*/

        function drawBackGround(){

            c.save();

            c.translate(center.x, center.y); /*平移变换*/

            /*绘制刻度*/

            function drawScale(){

              c.moveTo(radius - scale, 0);

              c.lineTo(radius, 0); 

            };

            c.beginPath();

            c.arc(0, 0, radius, 0, 2*Math.PI, true);

            c.closePath();

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

              drawScale();

              c.rotate(hourangle); /*旋转变换*/

            };

            /*绘制时间(3,6,9,12)*/

            c.font = " bold 30px impack"

            c.fillText("3", 110, 10);

            c.fillText("6", -7, 120);

            c.fillText("9", -120, 10);

            c.fillText("12", -16, -100);

            c.stroke();

            c.restore();

        };

        /*绘制时针(h: 当前时(24小时制))*/

        this.drawHourHand = function(h){

            h = h === 0? 24: h;

            c.save();

            c.translate(center.x, center.y); 

            c.rotate(3/2*Math.PI);

            c.rotate(h*hourangle);

            c.beginPath();

            c.moveTo(0, 0);

            c.lineTo(hourHandLength, 0);

            c.stroke();

            c.restore();

        };

        /*绘制分针(m: 当前分)*/

        this.drawMinHand = function(m){

            m = m === 0? 60: m;

            c.save();

            c.translate(center.x, center.y); 

            c.rotate(3/2*Math.PI);

            c.rotate(m*minangle);

            c.beginPath();

            c.moveTo(0, 0);

            c.lineTo(minHandLength, 0);

            c.stroke();

            c.restore();

        };

        /*绘制秒针(s:当前秒)*/

        this.drawSecHand = function(s){

            s = s === 0? 60: s;

            c.save();

            c.translate(center.x, center.y); 

            c.rotate(3/2*Math.PI);

            c.rotate(s*minangle);

            c.beginPath();

            c.moveTo(0, 0);

            c.lineTo(secHandLength, 0);

            c.stroke();

            c.restore();

        };

        /*依据本机时间绘制时钟*/

        this.drawClock = function(){

            var me = this;

            function draw(){

              var date = new Date();

              Canvas.clearCxt();

              drawBackGround();

              drawCenter();

              me.drawHourHand(date.getHours() + date.getMinutes()/60);

              me.drawMinHand(date.getMinutes() + date.getSeconds()/60);

              me.drawSecHand(date.getSeconds());

            }

            draw();

            setInterval(draw, 1000);

        }; 

    };

    var main = function(){

        var clock = new Canvas.Clock();

        clock.drawClock();

    };

    23、rem布局中的尺寸是怎样计算的,实际举例说明一下?

    答:其实rem布局的本质是等比缩放,一般是基于宽度,试想一下如果UE图能够等比缩放,假设我们将屏幕宽度平均分成100份,每一份的宽度用x表示,x = 屏幕宽度 / 100,如果将x作为单位,x前面的数值就代表屏幕宽度的百分比。

    24、Rem 布局原理?

    答:rem和em很容易混淆,其实两个都是css的单位,并且也都是相对单位,现有的em,css3才引入的rem,em可以让我们的页面更灵活,更健壮,比起到处写死的px值,em似乎更有张力,改动父元素的字体大小,子元素会等比例变化,这一变化似乎预示了无限可能

    rem布局的本质是等比缩放,一般是基于宽度,试想一下如果UE图能够等比缩放,那假设我们将屏幕宽度平均分成100份,每一份的宽度用x表示,x = 屏幕宽度 / 100,如果将x作为单位,x前面的数值就代表屏幕宽度的百分比

    25、transform后面可以设置那些属性?分别是干什么用的?

    答: transform的含义是:改变,使…变形;转换

    CSS3 transform常用属性:rotate() / skew() / scale() / translate(,) ,分别还有x、y之分,比如:rotatex() 和 rotatey()

    transform:rotate():

    含义:旋转;其中“deg”是“度”的意思,如“10deg”表示“10度”下同。

    .demo_transform1{-webkit-transform:rotate(10deg);-moz-transform:rotate(10deg)}

    transform:skew():

    含义:倾斜;

    .demo_transform2{-webkit-transform:skew(20deg);-moz-transform:skew(20deg)}

    transform:scale():

    含义:比例;“1.5”表示以1.5的比例放大,如果要放大2倍,须写成“2.0”,缩小则为负“-”。

    .demo_transform3{-webkit-transform:scale(1.5);-moz-transform:scale(1.5)}

    transform:translate():

    含义:变动,位移;如下表示向右位移120像素,如果向上位移,把后面的“0”改个值就行,向左向下位移则为负“-”。

    .demo_transform4{-webkit-transform:translate(120px,0);-moz-transform:translate(120px,0)}

    26、实现两个页面跳转的方式?

    答:window.location.href='hello.html';

    window.history.back(-1); 

    window.navigate("top.jsp");

    self.location=’top.htm’;

    27、写一个去重的函数?

    28、写一个排序的函数?

    答:js中要实现数据排序,其实只需要用sort函数就可以解决了,如下代码是sort和其他排序算法的区别和耗时。

    Sort = {}

    Sort.prototype = {

          // 利用sort进行排序 

          systemSort:function(array){ 

              return array.sort(function(a, b){ 

                  return a - b; 

              }); 

          }, 

          // 冒泡排序 

          bubbleSort:function(array){ 

              var i = 0, len = array.length, 

                  j, d; 

              for(; i<len; i++){ 

                  for(j=0; j<len; j++){ 

                      if(array[i] < array[j]){ 

                          d = array[j]; 

                          array[j] = array[i]; 

                          array[i] = d; 

                      } 

                  } 

              } 

              return array; 

          },

          // 快速排序 

          quickSort:function(array){ 

              //var array = [8,4,6,2,7,9,3,5,74,5]; 

              //var array =[0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7]; 

              var i = 0; 

              var j = array.length - 1; 

              var Sort = function(i, j){ 

                  // 结束条件 

                  if(i == j ){ return };

                  var key = array[i]; 

                  var tempi = i; // 记录开始位置 

                  var tempj = j; // 记录结束位置 

                  while(j > i){ 

                      // j <<-------------- 向前查找 

                      if(array[j] >= key){ 

                          j--; 

                      }else{ 

                          array[i] = array[j] 

                          //i++ ------------>>向后查找 

                          while(j > ++i){ 

                              if(array[i] > key){ 

                                  array[j] = array[i]; 

                                  break; 

                              } 

                          } 

                      } 

                  }

                  // 如果第一个取出的 key 是最小的数 

                  if(tempi == i){ 

                      Sort(++i, tempj); 

                      return ; 

                  }

                  // 最后一个空位留给 key 

                  array[i] = key; 

                  // 递归 

                  Sort(tempi, i); 

                  Sort(j, tempj);

              } 

              Sort(i, j);

              return array; 

          },   

          // 插入排序 

          insertSort:function(array){ 

              // http://baike.baidu.com/image/d57e99942da24e5dd21b7080 

              // http://baike.baidu.com/view/396887.htm 

              // var array = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7]; 

              var i = 1, j, temp, key, len = array.length;

              for(; i < len; i++){ 

                  temp = j = i; 

                  key = array[j]; 

                  while(--j > -1){ 

                      if(array[j] > key){ 

                          array[j+1] = array[j]; 

                      }else{

                          break;

                      }

                  }

                  array[j+1] = key; 

              }

              return array; 

          }, 

          // 希尔排序 

          //Jun.array.shellSort(Jun.array.df(10000)); 

          shellSort:function(array){ 

              // http://zh.wikipedia.org/zh/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F 

              // var array = [13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10];

              // var tempArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1]; 

              // reverse() 在维基上看到这个最优的步长 较小数组 

              var tempArr = [1031612713, 217378076, 45806244, 9651787, 2034035, 428481, 90358, 19001, 4025, 836, 182, 34, 9, 1] 

                  //针对大数组的步长选择 

              var i = 0; 

              var tempArrLength = tempArr.length; 

              var len = array.length; 

              var len2 =  parseInt(len/2); 

              for(;i < tempArrLength; i++){ 

                  if(tempArr[i] > len2){ 

                      continue; 

                  }

                  tempSort(tempArr[i]); 

              }

              // 排序一个步长 

              function tempSort(temp){ 

                  //console.log(temp) 使用的步长统计 

                  var i = 0, j = 0, f, tem, key; 

                  var tempLen = len%temp > 0 ?  parseInt(len/temp) + 1 : len/temp;         

                  for(;i < temp; i++){// 依次循环列 

                      for(j=1;/*j < tempLen && */temp * j + i < len; j++){

                            //依次循环每列的每行 

                          tem = f = temp * j + i; 

                          key = array[f];   

                          while((tem-=temp) >= 0){ 

                                // 依次向上查找

                              if(array[tem] > key){

                                  array[tem+temp] = array[tem];

                              }else{

                                  break;

                              }

                          }

                          array[tem + temp ] = key;

                      }

                  }

              }

              return array;

          }

    }

    testArrs = [];

    for (var i = 0; i < 5000; i++) {

      testArrs.push(Math.random());

    };

    console.log(+new Date());

    Sort.prototype.systemSort(testArrs);

    console.log(+new Date());

    Sort.prototype.bubbleSort(testArrs);

    console.log(+new Date());

    Sort.prototype.quickSort(testArrs);

    console.log(+new Date());

    ss = Sort.prototype.insertSort(testArrs);

    //console.log(ss.toString);

    console.log(+new Date());

    oo = Sort.prototype.shellSort(testArrs);

    console.log(+new Date());

    //console.log(oo.toString());个排序算法和sort函数的比较

    29、vue是怎么传值的

    答:父子之间的传值

    父组件向子组件传值 通过prop 子组件在props中创建一个属性,用以接收父组件传过来的值 ,子组件向父组件传值 在响应该点击事件的函数中使用$emit来触发一个自定义事件 在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听

      非父子之间的通讯

    可以通过eventBus来实现通信, 所谓eventBus就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件,ventBus = new Vue();

      组件1触发:

    <div @click="eve"></div>

    methods: {

        eve() {

            eventBus.$emit('change','hehe'); //Hub触发事件

        }

    }123456

    组件2接收:

    <div></div>

    created() {

        eventBus.$on('change', () => { //Hub接收事件

            this.msg = 'hehe';

        });

    }123456

    这样就实现了非父子组件之间的通信了.原理就是把eventBus当作一个中转站!

    30、网站优化时怎么做数据分析?

      答:网站优化时,我们需要每天在百度统计中查看我们网站的每日流量,还有在各大站长平台中查看网站的收录量,网站关键词流量,还有就是每天要用站长工具查看网站的基本情况。这些数据都是最基础的。

    31、外边距合并怎么解决?

    答:水平margin不会被合并,垂直margin会被合并

          1.设置了的overflow属性的盒模型,则其与子元素之间的垂直margin不会合并,但其与父元素之间、与相邻元素之间的margin会合并。(overflow取值为visible除外)

          2.设置了float属性的盒模型,则其与相邻元素之间、其与父元素之间、其与子元素之间的垂直margin都不会被合并。

          3.设置了绝对定位position:absolute的盒模型,则其与相邻元素之间、其与父元素之间、其与子元素之间的垂直margin都不会被合并。(但应注意position:absolute对其后元素的position的影响)

    4、设置了display:inline-block的盒模型,则其与相邻元素之间、其与父元素之间、其与子元素之间的垂直margin都不会被合并。

    相邻元素的margin是否被折叠会影响元素的位置。

    防止外边距合并解决方案:

      1.防止元素与子元素margin重叠:

    用内层元素的margin通过外层元素的padding代替;

                内层元素透明边框 border:20px solid transparent/父元素background-color;

      外层元素 overflow:hidden;/overflow:auto;

    2.防止元素与子元素、与父元素。与相邻元素的重合:

                设置元素绝对定位 postion:absolute;或float:left;或display:inline-block;

    32、H5里面的跨域?

      答:由于同源策略的限制,JavaScript 跨域的问题,一直是一个颇为棘手的问题。但是,HTML5 提供了在网页文档之间互相接收与发送信息的功能postMessage,IE8就开始支持了。使用这个功能,只要获取到网页所在窗口对象的实例,不仅同源(域 + 端口号)的 Web 网页之间可以互相通信,甚至可以实现跨域通信。

    1、简介:otherWindow.postMessage(message, targetOrigin);

    要想接收从其他窗口发送来的信息,必须对窗口对象的 onmessage 事件进行监听,其它窗口可以通过 postMessage 方法来传递数据。postMessage方法使用两个参数:第一个参数为所发送的消息文本,但也可以是任何 JavaScript 对象(通过 JSON 转换对象为文本),第二个参数为接收消息的对象窗口的 URL 地址,可以在 URL 地址字符串中使用通配符'*'指定全部地。

    2、作用:允许程序员跨域在两个窗口/frames间发送数据信息。基本上,它就像是跨域的AJAX,但不是浏览器跟服务器之间交互,而是在两个客户端之间通信。

    3、postMessage语法

    otherWindow.postMessage(msg,targetOrigin)

    (1)otherWindow:对接收信息页面的window的引用。可以是:

    (a)、内联框架iframe的contentWindow属性

    (b)、通过window.open方法打开的新窗口的window

    (c)、window.opener(父页面)

    (d)、通过name或window.frames[i]。

    如果你使用postMessage时没有带window,默认你就是用的本页面的window来调用了它。

    (2)、参数说明

    msg

    这就是要传递的消息了。它可以是一切javascript参数,如字符串,数字,对象,数组,而不是和json一样只局限于字符串,很强大!

    targetOrigin

    这个参数称作“目标域”,用于限制otherWindow,“*”表示不作限制。

    注意啦,是目标域不是本域!比如,你想在2.com的网页上往1.com网页上传消息,那么这个参数就是“http://1.com/”,而不是2.com.

    另外,一个完整的域包括:协议,主机名,端口号。如:http://g.cn:80/

    (3)其他页面获取postMessage传过来的消息

    要对postMessage传来的消息进行处理,就要在其他页面或子页面上加一个onmessage事件。如:

    window.addEventListener('message',function(event){

    console.log(event.data,event.origin,event.source);

    })

    注意:最好是通过addEventListener或attachEvent来加入onmessage事件,而不要直接window.onmessage=function(){},因为有的浏览器这样加会识别不了(如低版Firefox)

    这个onmessage事件接受一个参数,就是代码里的e,实际上他就是一个event对象。但他里面有很明显的3个参数与其他event对象不一样,即:

    (a)data:顾名思义,是传递来的message

    (b)source:发送消息的窗口对象

    (c)origin:发送消息窗口的源url(协议+主机+端口号).比如从2.com往1.com发了消息,那么1.com收到消息时,e.origin就是2.com

    最重要的就是data了,你可以用e.data取得他,然后做后续操作了。不过为了安全,你最好先判断一下e.source和e.origin是不是正确来源,再作操作。

    33、你是怎么处理手机端适配的 如果横屏的话怎么办

        答:在移动端中我们经常碰到横屏竖屏的问题,那么我们应该如何去判断或者针对横屏、竖屏来写不同的代码呢。

    首先在head中加入如下代码:

    1

    <</code>meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>

    针对上述viewport标签有如下说明

    1)、content中的width指的是虚拟窗口的宽度。

    2)、user-scalable=no就一定可以保证页面不可以缩放吗?NO,有些浏览器不吃这一套,还有一招就是minimum-scale=1.0, maximum-scale=1.0 最大与最小缩放比例都设为1.0就可以了。

    3)、initial-scale=1.0 初始缩放比例受user-scalable控制吗?不一定,有些浏览器会将user-scalable理解为用户手动缩放,如果user-scalable=no,initial-scale将无法生效。

    4)、手机页面可以触摸移动,但是如果有需要禁止此操作,就是页面宽度等于屏幕宽度是页面正好适应屏幕才可以保证页面不能移动。

    5)、如果页面是经过缩小适应屏幕宽度的,会出现一个问题,当文本框被激活(获取焦点)时,页面会放大至原来尺寸。

    一:CSS判断横屏竖屏

    写在同一个CSS中

    @media screen and (orientation: portrait) {

    }

    @media screen and (orientation: landscape) {

    }

    分开写在2个CSS中

    竖屏

    1

    <</code>link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css">

    横屏

    1

    <</code>link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css">

    一:JS判断横屏竖屏

    //判断手机横竖屏状态:

    window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function() {

            if (window.orientation === 180 || window.orientation === 0) {

                alert('竖屏状态!');

            }

            if (window.orientation === 90 || window.orientation === -90 ){

                alert('横屏状态!');

            }

        }, false);

    //移动端的浏览器一般都支持window.orientation这个参数,通过这个参数可以判断出手机是处在横屏还是竖屏状态。

    34、MVC模式的意思是,软件可以分成三个部分?

    答:视图(View):用户界面。

    控制器(Controller):业务逻辑

    模型(Model):数据保存

    35、各部分之间的通信方式是什么?

    答: View 传送指令到 Controller

    Controller 完成业务逻辑后,要求 Model 改变状态

    Model 将新的数据发送到 View,用户得到反馈

    36、Vue.js特点

    答:简洁:页面由HTML模板+Json数据+Vue实例组成数据驱动:自动计算属性和追踪依赖的模板表达式组件化:用可复用、解耦的组件来构造页面轻量:代码量小,不依赖其他库快速:精确有效批量DOM更新模板友好:可通过npm,bower等多种方式安装,很容易融入

    相关文章

      网友评论

          本文标题:前端面试题实战1

          本文链接:https://www.haomeiwen.com/subject/oujagqtx.html