美文网首页
前端跳槽必备知识

前端跳槽必备知识

作者: seporga | 来源:发表于2019-03-11 23:07 被阅读0次

    一、页面布局

    CSS盒模型

    • 标准模型和IE模型


      image.png
    • 标准模型和IE模型的区别
      标准模型计算宽高时,只包含content的宽高
      IE模型计算宽高时,包含content、padding和border

    • CSS如何设置这两种模型

    box-sizing:content-box // 设置为标准模型(浏览器默认)
    box-sizing:border-box // 设置为IE模型
    
    • JS如何设置及获取盒模型的宽和高
    var dom = document.getElementById('dom')
    dom.style.width/height // 普适
    dom.currentStyle.width/height // 仅IE浏览器支持
    window.getComputedStyle(dom).width/height // Chrome、Firefox
    dom.getBoundingClientRect().width/height/left/top // 获取元素相对viewport(视窗)左上角的位置
    
    • 边距重叠问题
      两个兄弟盒子和包含关系的盒子,同时设置margin时,会以数值大的为主,数值小的会被忽略。解决办法是创建BFC。

    • 如何创建BFC(块级格式化上下文)
      float的值不为none时;
      position不为static或relative时,比如设置为absolute、fixed等
      display为table时
      overflow不为visible时,比如设置为hidden,scroll等

    二、DOM事件

    • DOM事件的级别
      DOM0:element.onclick = function(){} 或 <div onclick="alert('Hi~')"></div>
      DOM1:没有涉及事件标准的制定
      DOM2:element.addEventLister('click',function(){},false) // false 表示冒泡阶段触发
      DOM3:element.addEventLister('keyup',function(){},false) // 新增了很多事件类型

    • DOM事件模型
      冒泡、捕获

    • DOM事件流

    • DOM事件捕获的具体流程
      window --->document--->html--->body
      js中获取html节点的方法document.documentElement

    • Event对象的常见应用

    function(event){
      event.preventDefault() // 阻止事件默认行为
      event.stopPropagation() // 阻止冒泡,防止事件往上传递
      event.stopImmediatePropagation() // 同一个元素绑定了多个方法,这个方法可以阻止剩下未触发的事件
      event.currentTarget // 当前事件实际绑定的元素
      event.target // 事件代理时,实际触发事件的子元素,IE不支持
    }
    
    • 自定义事件
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>customEvent</title>
    </head>
    <style>
        .target {
            width: 200px;
            height: 40px;
            line-height: 40px;
            text-align: center;
            color: white;
            background: red;
        }
    </style>
    <body>
        <div class="target" id="target">目标元素</div>
    </body>
    <script>
        // 事件捕获演示
        var target = document.getElementById('target')
        window.addEventListener('click', function () {
            console.log('window 捕获')
        }, true)
    
        document.addEventListener('click', function () {
            console.log('document 捕获')
        }, true)
    
        document.documentElement.addEventListener('click', function () {
            console.log('html 捕获')
        }, true)
    
        document.body.addEventListener('click', function () {
            console.log('body 捕获')
        }, true)
    
        target.addEventListener('click', function () {
            console.log('target 捕获')
        }, true)
    
        // 事件捕获演示
        var target = document.getElementById('target')
        window.addEventListener('click', function () {
            console.log('window 冒泡')
        }, false)
    
        document.addEventListener('click', function () {
            console.log('document 冒泡')
        }, false)
    
        document.documentElement.addEventListener('click', function () {
            console.log('html 冒泡')
        }, false)
    
        document.body.addEventListener('click', function () {
            console.log('body 冒泡')
        }, false)
    
        target.addEventListener('click', function () {
            console.log('====  华丽的分割线  ======')
            console.log('target 冒泡')
        }, false)
    
        // 需要抛出事件的地方
        var eve = new Event('myEvent')
        target.addEventListener('myEvent', function () {
            console.log('dispatch自定义事件')
        })
        setTimeout(function () { // 3s后触发事件
            target.dispatchEvent(eve) // 注意这里dispatchEvent的是事件对象eve,而不是事件myEvent
        }, 3000)
    </script>
    </html>
    

    三、 HTTP协议

    http协议是一种无连接、无状态的协议

    • http报文的组成部分
      请求报文:请求行(协议)、请求头、空行、请求体
      响应报文:状态行、响应头、空行、响应体

    • http方法
      GET:获取资源
      POST:传输资源
      PUT:更新资源
      DELETE:删除资源
      HEAD:获取报文首部

    • GET和POST的区别
      GET在浏览器回退时是无害的,而POST会再次发送请求;
      GET产生的URL可以被收藏,而POST不可以;
      GET请求会被浏览器主动缓存,而POST不会,除非手动设置;
      GET请求只能进行url编码,而POST支持多种编码方式;
      GET请求参数会被完整保留在浏览器历史记录中,而POST中的参数不会被保留;
      GET请求在URL中传送的参数是有长度限制的,而POST没有限制;
      GET只接受ASCII字符,而POST没有限制;
      GET比POST更不安全,因为参数直接暴露在URL中,不能用来传敏感信息;
      GET参数通过URL传递,POST参数放在Request body中传递;

    • HTTP状态码
      1xx:指示信息—表示请求已经接受,正在处理
      2xx:成功—表示请求已经被成功接收
      3xx:重定向—要完成请求必须进行更进一步的操作
      4xx:客户端错误—请求有语法错误或请求无法实现
      5xx:服务端错误—服务器未能实现合法的请求
      例如:
      200 OK : 客户端请求成功;
      206 Partial Content:客户端发送了一个带有Range头的GET请求,服务器完成了它(请求音视频文件时);
      301 Moved Permanently:所请求的页面已经转移到新的url;
      304 Not Modified:客户端有缓存的文档发出了一个条件性的请求,服务器告诉客户端,原来的缓存的文档还可以继续使用;
      400 Bad Request:客户端请求有语法错误,不能被服务器所理解;
      403 Forbidden:被请求的页面禁止访问;
      500 Internal Server Error:服务器发生不可预期的错误;
      503 Server Unavailable:请求未完成,服务器临时过载或宕机。

    • 持久链接
      普通模式:http采用“请求-->应答”模式,每次请求或者应答,客户端和服务器都要重新建立一个连接,完成后立即断开;
      Keep-Alive模式:又称持久链接,连接重用,该模式使客户端到服务端的连接持久有效,当出现后继请求时,Keep-Alive功能避免建立或重连,http1.1 版本开始支持Keep-Alive模式。

    • 管线化
      管线化通过持久连接完成,仅http1.1支持此技术
      持久连接:请求1-->响应1-->请求2-->响应2-->请求3-->响应3
      管线化:请求1-->请求2-->请求3-->响应1-->响应2-->响应3

    四、原型链

    • 创建对象有几种方法
    // 第一种方式:字面量
    var o1 = {name:'o1'}
    var o2 = new Object({name:'o2'})
    // 第二种方式:构造函数
    function M(name){name:'03'}
    var o3 = new M()
    // 第三种方式:
    var M = function(name){this.name=name}
    var o3 = new M('o3')
    // 第四种方式
    var p = {name:'o4'}
    var o4 = Object.create(p)
    
    • 原型对象、构造函数、实例、原型链
      原型对象:构造函数的Prototype所指的对象,原型对象的contractor属性指向构造函数
      构造函数:使用new运算符操作的函数就是构造函数
      实例:构造函数new出来的


      前端跳槽必备知识
    • instanceof的原理
      instanceof通过比较实例对象__proto__属性所指的原型和构造函数prototype属性所指的原型,是否指向同一个原型,如果是则成立。

    var M = function(name){this.name=name}
    var o3 = new M('o3')
    o3 instanceof M // true
    o3 instanceof Object // false
    // 因此,instanceof无法准确判断实例的直接构造函数
    // 要准确判断,可以借助__proto__和constructor,例如:
    o3.__proto__.constructor===M // true 
    
    前端跳槽必备知识
    • 使用new运算符,发生了什么?
      1.创建一个新对象,它继承自foo.prototype;
      2.执行构造函数,传入相应参数,上下文(this)被指定为新实例;没有参数时,则省略传参这一步,因此,没有参数时new foo 等价于 new foo();
      3.如果构造函数返回了一个“对象”,则这个对象会取代new出来的结果。否则,new出来的结果为步骤1所创建的对象。

    五、面向对象

    <!-- 面向对象 -->
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>OOP</title>
    </head>
    <body>
        <div>面向对象,请打开控制台</div>
        <script type="text/javascript">
            // ==== 类的声明 ==== 
            function Animal() {
                this.name = 'name'
            }
            // ==== ES6中的class声明类 ==== 
            class Animal2 {
                constructor() {
                    this.name = 'name'
                }
            }
            console.log('==== 类的声明与实例化 ====')
            console.log('Animal', new Animal())
            console.log('Animal2', new Animal2())
    
            // ==== 借助构造函数实现继承(无法继承父类原型链上的属性和方法) ==== 
            function Parent1() {
                this.name = 'Parent1'
            }
            Parent1.prototype.p1 = 'p1'
            Parent1.prototype.say = function () { console.log('Say Hi~') }
            function Child1() {
                Parent1.call(this) // 用apply也可以,只是传参的方式不一样
                this.type = 'Child1'
            }
            console.log('==== 借助构造函数实现继承 ====')
            console.log('Child1', new Child1)
            console.log('Parent1', new Parent1)
    
            // ==== 借助原型链实现继承 ==== 
            function Parent2() {
                this.name = 'Parent2'
                this.arr = [1, 2, 3]
            }
            function Child2() {
                this.type = 'Child2'
            }
            Child2.prototype = new Parent2() // Parent2的实例赋值给Child2的prototype属性
            console.log('==== 借助原型链实现继承 ====')
            console.log('Child2的原型链上有了Parent2的属性和方法', new Child2()) // Child2的原型链上有了Parent2的属性和方法
            // 这种方法的缺点,实例共享父类的属性
            var s1 = new Child2()
            var s2 = new Child2()
            console.log('s1.arr', s1.arr)
            console.log('s2.arr', s2.arr)
            s1.arr.push('4') // 改变实例1的arr值
            // 改变实例1的arr值
            console.log('借助原型链实现继承缺点:实例共享父类的属性')
            console.log('s1.arr', s1.arr)
            console.log('s2.arr', s2.arr) // s2的值也被改变了
    
            // ==== 组合方式实现继承 ==== 
            function Parent3() {
                this.name = 'Parent3'
                this.arr = [1, 2, 3]
                console.log('Parent3被调用了')
            }
            console.log('==== 借助原型链实现继承,解决了构造函数和原型链的缺点。但是这个方法中,父类被调用了2次 ====')
            function Child3() {
                Parent3.call(this)
                this.type = 'Child3'
            }
            Child3.prototype = new Parent3()
            console.log('Child3', new Child3())
    
            // ==== 组合方式实现继承优化1,解决父类被调用两次问题 ==== 
            function Parent4() {
                this.name = 'Parent4'
                this.arr = [1, 2, 3]
                console.log('Parent4被调用了')
            }
            function Child4() {
                Parent4.call(this)
                this.type = 'Child4'
            }
            Child4.prototype = Parent4.prototype
            console.log('==== 组合方式实现继承优化1,解决父类被调用两次问题,但无法确定实例的直接构造函数了 =====')
            console.log('Child4', new Child4())
    
            // ==== 组合方式实现继承优化2,解决父类被调用两次问题 ==== 
            function Parent5() {
                this.name = 'Parent5'
                this.arr = [1, 2, 3]
                console.log('Parent5被调用了')
            }
            function Child5() {
                Parent5.call(this)
                this.type = 'Child5'
            }
            Child5.prototype = Object.create(Parent5.prototype) // Object.create只拷贝了原型链的部分,不包含新
            Child5.prototype.constructor = Child5
            console.log('==== 组合方式实现继承优化2,Object.create方法 =====')
            var s7 = new Child5()
            console.log('s7 instanceof Child5', s7 instanceof Child5)
            console.log('s7 instanceof Parent5', s7 instanceof Parent5)
            console.log('s7.__proto__.constructor === Child5', s7.__proto__.constructor === Child5)
    
        </script>
    </body>
    </html>
    

    六、通信

    • 什么是同源策略
      协议、域名、端口任何一个不一致就是跨域,同源策略是用于隔离潜在的恶意文件的关键的安全机制。

    • 同源策略有哪些限制
      1.Cookie、localStorage 和 indexDB无法获取
      2.DOM无法获取
      3.Ajax请求不能发送

    • 前后端如何通信
      1.Ajax:不支持跨域
      2.WebSocket:允许跨域
      3.CORS:新的通信标准,支持跨域通信和同源通信

    • 如何创建一个Ajax请求
      1.XMLHttpRequest对象的工作流程
      2.兼容性处理
      3.事件的触发条件
      4.事件的触发顺序

    • 跨域通信的集中方式
      1.JSONP

    window.hhh = function () {  // 定义全局函数名
       console.log('window.hhh')
    }
    var script = document.createElement('script') // 创建script标签
    script.src = 'https://www.baidu.com?callback=hhh'  // 向服务端传递callback名
    script.onload = script.onreadystatechange = function () { // 监听onload事件
      console.log('hahah')
      window.hhh() // 运行服务端返回的hhh函数,格式类似:hhh({data:xxx})
    }
    document.body.append(script) // append到body中,发起请求
    
    // 运行结果:
    // hahah
    // window.hhh
    

    2.Hash(地址中,"#"号后面的内容,hash值改变浏览器不刷新)
    3.postMessage
    4.WebSocket
    5.CORS(参考资料 http://www.ruanyifeng.com/blog/2016/04/cors.html

    七、安全

    1.CSRF(Cross-site request forgery)跨站请求伪造
    攻击原理:用户登录A网站,访问网站B,网站B伪造了一个指向A网站的GET请求并携带相关参数,此时浏览器会自动携带Cookie,A网站验证Cookie通过,并执行B网站伪造的GET请求。
    防御措施:Token验证、Referer验证、隐藏令牌

    2.XSS(Cross-site scripting)跨域脚本攻击
    攻击原理:不需要登录,利用漏洞,执行恶意脚本。
    防御措施:参考 http://www.imooc.com/learn/812

    3.两者区别
    XSS向页面注入脚本,在脚本中做想做的事情;CSRF利用接口漏洞,自动执行接口(一般要求用户已登录)

    算法

    • 排序
    • 堆栈、队列、链表
    • 递归
    • 波兰式和逆波兰式

    参考资料:https://coding.imooc.com/class/315.html

    八、一道经典的题目,考考大家对布局的掌握程度

    三栏布局:


    image.png
    • 答案:浮动、绝对定位、flex布局、表格布局、网格布局。
    • 拔高点:高度未知的情况下,哪种还能用?哪种不能用了?为什么?
    • 总结:语义化、代码书写规范、页面布局理解深刻、CSS基础要扎实、思维灵活且积极上进(掌握新的grid布局)

    参考答案:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>layout</title>
    </head>
    <style>
        html * {
            padding: 0;
            margin: 0;
        }
        .layout {
            margin-top: 20px;
        }
        .layout article>div {
            min-height: 100px;
        }
    </style>
    <body>
        <section class="layout float">
            <style>
                .left {
                    float: left;
                    width: 300px;
                    background: red;
                }
    
                .right {
                    float: right;
                    width: 300px;
                    background: blue;
                }
    
                .center {
                    background: green;
                }
            </style>
            <article class="left-right-center">
                <div class="left">300px</div>
                <div class="right">300px</div>
                <div class="center">
                    <h1>浮动解决方案</h1>
                    <p>这是内容</p>
                    <p>这是内容</p>
                    <p>这是内容</p>
                </div>
            </article>
        </section>
        <section class="layout absolute">
            <style>
                .layout.absolute .left-right-center>div {
                    position: absolute;
                }
    
                .layout.absolute .left {
                    left: 0;
                    width: 300px;
                    background: red;
                }
    
                .layout.absolute .center {
                    left: 300px;
                    right: 300px;
                    background: green;
                }
    
                .layout.absolute .right {
                    right: 0;
                    width: 300px;
                    background: blue;
                }
            </style>
            <article class="left-right-center">
                <div class="left">300px</div>
                <div class="right">300px</div>
                <div class="center">
                    <h1>绝对定位解决方案</h1>
                    <p>这是内容</p>
                    <p>这是内容</p>
                    <p>这是内容</p>
                </div>
            </article>
        </section>
    
        <section class="layout flexbox">
            <style>
                .layout.flexbox {
                    margin-top: 140px;
                }
    
                .layout.flexbox .left-right-center {
                    display: flex;
                }
    
                .layout.flexbox .left {
                    width: 300px;
                    background: red;
                }
    
                .layout.flexbox .center {
                    flex: 1;
                    right: 300px;
                    background: green;
                }
    
                .layout.flexbox .right {
                    width: 300px;
                    background: blue;
                }
            </style>
            <article class="left-right-center">
                <div class="left">300px</div>
                <div class="center">
                    <h1>flexBox解决方案</h1>
                    <p>这是内容</p>
                    <p>这是内容</p>
                    <p>这是内容</p>
                </div>
                <div class="right">300px</div>
            </article>
        </section>
    
        <section class="layout table">
            <style>
                .layout.table .left-right-center {
                    width: 100%;
                    height: 100px;
                    display: table;
                    padding: 0;
                    margin: 0;
                }
    
                .layout.table .left-right-center>div {
                    display: table-cell;
                }
    
                .layout.table .left {
                    width: 300px;
                    background: red;
                }
    
                .layout.table .center {
                    width: 100%;
                    background: green;
                }
    
                .layout.table .right {
                    width: 300px;
                    background: blue;
                }
            </style>
            <article class="left-right-center">
                <div class="left">300px</div>
                <div class="center">
                    <h1>表格布局解决方案</h1>
                    <p>这是内容</p>
                    <p>这是内容</p>
                    <p>这是内容</p>
                </div>
                <div class="right">300px</div>
            </article>
        </section>
    
    
        <section class="layout grid">
            <style>
                .layout.grid .left-right-center {
                    width: 100%;
                    height: 100px;
                    display: grid;
                    grid-template-rows: 100px;
                    grid-template-columns: 300px auto 300px;
                }
    
                .layout.grid .left {
                    background: red;
                }
    
                .layout.grid .center {
                    background: green;
                }
    
                .layout.grid .right {
                    background: blue;
                }
            </style>
            <article class="left-right-center">
                <div class="left">300px</div>
                <div class="center">
                    <h1>网格布局解决方案</h1>
                    <p>这是内容</p>
                    <p>这是内容</p>
                    <p>这是内容</p>
                </div>
                <div class="right">300px</div>
            </article>
        </section>
    
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:前端跳槽必备知识

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