美文网首页
前端知识体系总结

前端知识体系总结

作者: 笑极 | 来源:发表于2016-12-16 22:52 被阅读74次

    数据结构与算法


    栈和队列的区别

    网络基础


    HTTP 无状态怎么理解

    可以从REST的角度来理解这个问题。我们知道REST风格是无状态的。而REST是基于HTTP协议的,所以REST的无状态基本就可以解释HTTP的无状态。

    TCP三次握手与四次挥手

    三次握手
    为了准确无误地将数据送到目标处,TCP采用三次握手策略,过程中使用了TCP的标志:SYN和ACK.
    三次握手
    Client --> 置SYN标志 序列号 = J,确认号 = 0 ----> Server
    Client <-- 置SYN标志 置ACK标志 序列号 = K, 确认号 = J + 1 <-- Server
    Clinet --> 置ACK标志 序列号 = J + 1,确认号 = K + 1 --> Server
    四次挥手
    Client -> 发送FIN 序列号 = J,确认号 = 0 --> Server
    Server -> 发送ACK 确认号 = J + 1
    Server -> 发送FIN 序列号 = K, 确认号 = 0 -> Client
    Client -> 发送ACK 确认号 = K+1

    HTTPS

    HTTPS是在HTTP与TCP之间添加一个安全协议层(SSL或TSL).
    网络请求中往往中间需要很多服务器或者路由器的转发,中间的节点都可能篡改信息,而如果使用HTTPS,密钥在请求客户端和终点站才有,所以相对于HTTP会更安全,就是因为HTTPs利用SSL/TSL协议传输,它包含证书等安全信息,保证了传输过程的安全性。

    前端其他问题


    前端工程价值

    • 解放前后端互相在开发进度上的依赖问题,前后端可以同时进行
    • 为简化用户使用,提高交互体验/用户体验
    • 解决浏览器兼容问题
    • 提高浏览速度(性能)
    • 跨平台应用的支持
    • 展现数据,数据处理
    • 降低后端压力

    浏览器缓存技术

    ** Etag **

    当发送一个服务器的请求时,浏览器会首先进行缓存过期的判断,浏览器根据缓存过期的时间判断缓存文件是否过期。

    • 若没有过期,则不向服务器发送请求,直接使用缓存中的结果

    Session Cookie LocalStorage

    全局环境与局部环境

    JS对象 BOM DOM

    http://www.runoob.com/jsref/dom-obj-event.html

    浏览器的基本组成与页面渲染原理

    为什么不能频繁操作DOM

    重排与重绘

    前端模块化


    https://segmentfault.com/p/1210000007731421?from=singlemessage&isappinstalled=1
    CommonJs规范 - NodeJs实现 同步
    分支 异步
    AMD RequireJs
    CMD SeaJs
    UMD 前后端整合
    ES6 - I import export

    前端优化


    前端兼容性


    渐进增强和优雅降级

    ** 渐进增强 ** :针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
    ** 优雅降级 ** :一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

    前端安全性


    常见的几种安全攻击

    SQL 注入
    XSS
    CSRF

    前端工具


    模块打包工具

    ** Webpack **

    1. 模块打包工具
    1. 管理依赖模块间依赖,生成优化并且合并后的静态资源文件
    2. 编译输出静态文件,将代码分割成不同的chunk,实现按需加载,降低初始化时间
    3. 所有文件都是模块, html, js, css, 图片等
    4. 模块加载器, 支持串联操作
    5. 以commonJs的形式书写,但对AMD/CMD的支持也比较全面,方便旧项目进行代码迁移

    HTML5


    Webworker

    Js中的多线程实现

    Websocket

    SVG

    Canvas

    CSS


    position的值, relative和absolute分别是相对于谁进行定位的?

    盒模型

    IE盒模型与其他浏览器的盒模型

    CSS选择器的优先级

    JavaScript


    ES6

    参考:http://es6.ruanyifeng.com/

    Js运行机制

    http://www.ruanyifeng.com/blog/2014/10/event-loop.html

    • Javascript 是单线程
      Javascript 的单线程与它的用途有关
    • 任务队列
      任务可分为两种,一种是同步任务,一种是异步任务。
      ** 同步任务 :在主线程上排队执行的任务,只有前一个任务执行完毕后,才能执行后一个任务;
      ** 异步任务 :不进入主线程,而进入任务队列(task queue)的任务,只有任务队列通知主线程,某个异步任务要以执行了,该任务才会进入主线程执行。
      ** 异步任务运行机制如下:

      Paste_Image.png
      1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
      2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
      3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
      4)主线程不断重复上面的第三步。
      ** 只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。
    • 事件和任务队列
      ** 任务队列 **
    1. 是一个事件的队列,也可以理解成是消息队列。主线程读取任务队列就是读取里面有哪些事件。
    2. 任务队列里面不止有IO设备的事件,也有用户操作产生的事件。只要指定过回调函数,这些事件发生时就会进入任务队列中,等待主线程读取。主线程执行异步任务,就是执行对应的回调函数。
    3. 主线程会首先检查执行时间,某些事件只有到了规定的时间,才能返回主线程。如setTimeout().
      ** Event Loop **
      主线程从事件队列中读取事件的过程是不断循环的,所以整个的运行机制就是一个Event Loop,也叫事件循环。


      Paste_Image.png
    4. 定时器
      除了放置异步任务的事件,"任务队列"还可以放置定时事件,即指定某些代码在多少时间之后执行。这叫做"定时器"(timer)功能,也就是定时执行的代码。
      setTimeout()
      setInterval()
      HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。在此之前,老版本的浏览器都将最短间隔设为10毫秒。另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常不会立即执行,而是每16毫秒执行一次。这时使用requestAnimationFrame()的效果要好于setTimeout()。
      需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。

    Js事件模型

    参考:https://segmentfault.com/a/1190000006934031?from=singlemessage&isappinstalled=1
    DOM事件探秘

    • ** 发布订阅模式(观察者模式)**
      Javascript的事件模型基于发布请阅模式,可以让多个观察者对象同时监听某一个主题对象,这个主题对象的状态变化会通知所有的订阅者,使得它们能够做出反应。
      以下是用js实现的一个发布订阅模式
    var events = (function () {
        var topics = {};
        return {
            publish: function (topic, info) {
                console.log("publish a topic:" + topic);
                if (topics.hasOwnProperty(topic)) {
                    topics[topic].forEach(function(handler) {
                        handler(info ? info : {});
                    });
                }
            },
            subscribe: function(topic, handler) {
                console.log("subscribe an topic" + topic);
                if (!topics.hasOwnProperty(topic)) {
                    topics[topic] = [];
                }
                topics[topic].push(handler);
            },
            remove: function(topic, handler) {
                if (!topics.hasOwnProperty(topics)) {
                    return;
                }
                var handlerIndex = -1;
                topics[topic].forEach(function (element, index) {
                    if (element === handler) {
                        handlerIndex = index;
                    }
                });
                if (handlerIndex >= 0) {
                    topics[topic].splice(handlerIndex, 1);
                }
            }
        };
    })();
    var handler = function (info) {
        console.log(info);
    }
    events.subscribe("hello", handler);
    events.publish("hello", "hello world");
    
    • ** 事件与事件流 **
      事件是与浏览器或文档交互的瞬间,如点击按钮,填写表格等,它是JS与HTML之间交互的桥梁。DOM是树形结构,如果同时给父子节点都绑定事件时,当触发子节点的时候,这两个事件的发生顺序如何决定?这就涉及到事件流的概念,它描述的是页面中接受事件的顺序。
      事件流有两种:
      ** 事件冒泡(Event Capturing): ** 是一种从下往上的传播方式。事件最开始由最具体的元素(文档中嵌套层次最深的那个节点接受, 也就是DOM最低层的子节点), 然后逐渐向上传播到最不具体的那个节点,也就是DOM中最高层的父节点。
      ** 事件捕获(Event Bubbling): **与事件冒泡相反。事件最开始由不太具体的节点最早接受事件, 而最具体的节点最后接受事件。
    • ** 事件模型 **
      ** DOM 0级模型 **
      HTML代码中直接绑定:
    <input type="button" onclick="fun()">
    

    通过JS代码指定属性值:

    var btn = document.getElementById('.btn');btn.onclick = fun;
    

    移除监听函数:

    btn.onclick = null;
    

    这种方式所有浏览器都兼容,但是逻辑与显示并没有分离。
    ** IE事件模型 **
    IE事件模型共有两个过程:
    事件处理阶段(target phase)。事件到达目标元素, 触发目标元素的监听函数。
    事件冒泡阶段(bubbling phase)。事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
    事件绑定监听函数的方式如下:

    attachEvent(eventType, handler)
    

    事件移除监听函数的方式如下:

    detachEvent(eventType, handler)
    

    参数说明:
    eventType指定事件类型(注意加on)
    handler是事件处理函数
    Example:

    var btn = document.getElementById('.btn');
    btn.attachEvent(‘onclick’, showMessage);
    btn.detachEvent(‘onclick’, showMessage);
    

    ** DOM 2级模型 **
    属于W3C标准模型,现代浏览器(除IE6-8之外的浏览器)都支持该模型。在该事件模型中,一次事件共有三个过程:
    事件捕获阶段(capturing phase)。事件从document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
    事件处理阶段(target phase)。事件到达目标元素, 触发目标元素的监听函数。
    事件冒泡阶段(bubbling phase)。事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
    事件绑定监听函数的方式如下:

    addEventListener(eventType, handler, useCapture)
    

    事件移除监听函数的方式如下:

    removeEventListener(eventType, handler, useCapture)
    

    Example:

    var btn = document.getElementById('.btn');
    btn.addEventListener(‘click’, showMessage, false);
    btn.removeEventListener(‘click’, showMessage, false);
    

    参数说明:
    eventType指定事件类型(不要加on)
    handler是事件处理函数
    useCapture是一个boolean用于指定是否在捕获阶段进行处理,一般设置为false与IE浏览器保持一致。
    DOM事件模型中的事件对象常用属性:

    • type用于获取事件类型
    • target获取事件目标
    • stopPropagation()阻止事件冒泡
    • preventDefault()阻止事件默认行为
      IE事件模型中的事件对象常用属性:
    • type用于获取事件类型
    • srcElement获取事件目标
    • cancelBubble阻止事件冒泡
    • returnValue阻止事件默认行为

    Javascript垃圾回收机制

    ** 标记清除 ** -> 最常见的垃圾回收方式
    这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
    ** 引用计数 ** -> 会出现因为循环引用而出现的无法回收而导致的内存泄漏
    参考: http://www.jianshu.com/p/80ed3805edc3

    创建对象的几种方式

    • ** 使用{}
    var bar = {
      color: "blue"
    };
    
    • ** 使用new关键字 **
    var bar = new Object();
    bar.color = "blue";
    
    • ** 使用构造函数 **
    var Fun = function (color) {
      this.color = color;
    }
    var bar = new Fun();
    

    面向对象与继承的几种方式

    ** 原型编程泛型基本规则 **

    • 所有的数据都是对象
    • 要得到一个对象,不是通过 实例化类,而是找到一个对象作为原型并克隆它
    • 对象会记住它的原型
    • 如果对象本身无法响应某个请求,它会把这个请求委托给它自己的原型
      ** 实现方式 **
      http://www.jb51.net/article/81766.htm

    解决跨域问题

    Jsonp
    Cors
    Document.domain
    Document.name
    HTML5 postMessage

    AJAX

    创建过程
    (1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
    (2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
    (3)设置响应HTTP请求状态变化的函数.
    (4)发送HTTP请求.
    (5)获取异步调用返回的数据.(6)使用JavaScript和DOM实现局部刷新.
    参考:https://segmentfault.com/a/1190000004322487

    说说你对作用域链的理解

    作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。

    闭包

    实现延迟打印1-5

    for (var i = 0; i < 5; i++) {
      (function (i) {
        setTimeout(function () {
          console.log(i)
        }, i * 1000)
      })(i);
    }
    
    for (var i = 0; i < 5; i++) {
      setTimeout(function (i) {
        return function() { console.log(i); };
      }(i), i * 1000)
    }
    
    [1,2,3,4,5,6].forEach(i => {
        setTimeout(function () {
          console.log(i)
        }, i * 1000);
    });
    

    严格模式 (use strict)

    • 非严格模式下有些错误会在运行时被悄悄地忽略掉,而在严格模式下,这些错误会被抛出来,从而方便debug,通常来说,这是一种很好的实践。
    • 防止给未声明的变量赋值
    • 非严格模式下如果引用的this是null或者undefined的话会自动将this指向global对象,这种情况会造成一些比较难发现且头疼的bug。而在严格模式下,则会抛出错误。
    • 防止在一个对象内重复定义属性。
    • 安全使用eval()
    • delete操作符

    如何判读一个变量是个整数 (实现 isInteger(x))

    在ES6中,Number.isInteger() 可以用来判断是否为整数。
    在ES6之前的版本中这个问题则比较复杂,因为numberic的值通常是作为一个浮点数来存储的,只能用比较取巧的方式来实现这样的判断逻辑。

    function isInteger(x) { return (x^0) === x; }
    function isInteger(x) { return Math.round(x) === x; }
    function isInteger(x) { 
      return  (typeof x === "number") && (x % 1 === 0;;
    }
    

    此外也可以使用parseInt来实现

    function isInteger(x) { return parseInt(x, 10) === x;}
    

    数组操作 (split, reverse, push, slice, concat)

    What will the code below output to the console and why?

    var arr1 = "john".split('');
    var arr2 = arr1.reverse();
    var arr3 = "jones".split('');
    arr2.push(arr3);
    console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
    console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));
    

    JavaScript 设计模式


    Angular


    双向绑定如何实现

    脏检查机制

    React


    虚拟DOM 实现机制

    JQuery


    Jquery 绑定事件的方法

    target.on("click");
    target.click(function() {
    });
    target.live("click", function () {
    });
    target.bind("click", function () {
    });

    #### Jquery的链式操作如何实现
    
    # 正则表达式
    ****
    #### 语法
    > https://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx
    
    #### 验证身份证
    > ```
    var reg=/^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/;
    

    面试题


    更多面试题: https://www.toptal.com/javascript/interview-questions

    鼠标点击页面中的任意标签,alert标签名称 (兼容性)

    <script type="text/javascript" >
    document.onClick() = function(event) {
        var e = event || window.event;
        var src = event.target || event.srcElement;
        alert(src.tagName.toLowercase());
    }
    </script>
    

    异步加载js方案,不少于两种

    ** 同步加载 **

    就是我们平时使用的最多的方式,在页面中使用script标签
    这种模式也叫阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当加载完成,才能进行下一步的操作,所以默认同步执行才是比较安全的。但是这种方式会造成页面的阻塞,所以一般建议把<script>标签放在<body>结尾,这样尽可能减少页面阻塞。

    ** 异步加载 **

    异步加载 又叫非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理。主要有以下几中方式:

    • ** Script Dom Element **
    (function() {
        var scriptEle = document.createElement("script");
        scriptEle.type = "text/javascript";
        scriptEle.async = true;
        scriptEle.src="http://xxx/jquery.js";
        var x = document.getElementByTagName("head")[0];
        x.insertBefore(scriptEle, x.firstChild);
    })();
    

    google的使用方式

    (function(){;
        var ga = document.createElement('script'); 
        ga.type = 'text/javascript'; 
        ga.async = true; 
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
        var s = document.getElementsByTagName('script')[0]; 
        s.parentNode.insertBefore(ga, s); 
    })();
    

    缺点: 执行完成之前会阻止onLoad事件的触发,而现在很多页面的代码都会在onLoad的时候做一些额外的渲染动作,所以还是会阻塞部分页面的初始化的处理。

    • ** onload时的异步加载 **
    ;(function () {
      if (window.attachEvent) {
        window.attachEvent('load', asyncLoad)
      } else {
        window.addEventListener('load', asyncLoad)
      }
      var asyncLoad = function () {
        var scriptEle = document.createElement('script')
        scriptEle.type = 'text/javascript'
        scriptEle.async = true
        scriptEle.src = 'http://xxx/jquery.js'
        var x = document.getElementByTagName('head')[0]
        x.insertBefore(scriptEle, x.firstChild)
      }
    })()
    

    注:DOMContentLoaded与load区别
    前者是在document 已经解析完成,页面中的dom元素可用,但是页面中的图片,视频,音频等资源还未加载完,作用同jquery的ready. 后者的区别在于页面中所有资源包括js都加载完成。

    • ** 其他方法**
      ** XHR Injection **
      通过XMLHttpRequest来获取javascript,然后创建一个script元素插入到DOM结构中。ajax请求成功后设置script.text为请求成功后返回的responseText
    var getXmlHttp = function () {
      var obj
      if (window.XMLHttpRequest)
        obj = new XMLHttpRequest()
      else
        obj = new ActiveXObject('Microsoft.XMLHTTP')
      return obj
    }
    var xhr = getXmlHttp()
    xhr.open('GET', 'http://xxx.com/jquery.js', true)
    xhr.send()
    xhr.onReadyStateChange = function () {
      if (xhr.readyState == 4 && xhr.status == 200) {
        var script = document.createElement('script')
        script.text = xhr.response.text
        document.getElementsByTagName('head')[0].appendChild(script)
      }
    }
    

    ** XHR Eval **
    与XHR Injection对responseText的执行方式不同,直接把responseText放在eval()函数里面执行。
    ** Script In IFrame **
    在父窗口插入一个iframe元素,然后再iframe中执行加载JS的操作。

    var insertJS = function(){alert(2)};
        var iframe = document.createElement("iframe");
        document.body.appendChild(iframe);
        var doc = iframe.contentWindow.document;//获取iframe中的window要用contentWindow属性。
        doc.open();
        doc.write("<script>var insertJS = function(){};<\/script><body onload='insertJS()'></body>");
        doc.close();
    
    • ** HTML5新属性:async和defer属性 **
      ** defer属性 **:IE4.0就出现。defer属声明脚本中将不会有document.write和dom修改。浏览器会并行下载其他有defer属性的script。而不会阻塞页面后续处理。注:所有的defer脚本必须保证按顺序执行的。
    <script type="text/javascript" defer></script>
    

    ** async属性 **:HTML5新属性。脚本将在下载后尽快执行,作用同defer,但是不能保证脚本按顺序执行。他们将在onload事件之前完成。

    <script type="text/javascript" defer></script>
    

    Firefox 3.6、Opera 10.5、IE 9和最新的Chrome和Safari都支持async属性。可以同时使用async和defer,这样IE 4之后的所有IE都支持异步加载。
    没有async属性,script将立即获取(下载)并执行,期间阻塞了浏览器的后续处理。如果有async属性,那么script将被异步下载并执行,同时浏览器继续后续的处理。


    ** 总结 **: 对于支持HTML5的浏览器,实现JS的异步加载只需要在script元素中加上async属性,为了兼容老版本的IE还需加上defer属性;对于不支持HTML5的浏览器(IE可以用defer实现),可以采用以上几种方法实现。原理基本上都是向DOM中写入script或者通过eval函数执行JS代码,你可以把它放在匿名函数中执行,也可以在onload中执行,也可以通过XHR注入实现,也可以创建一个iframe元素,然后在iframe中执行插入JS代码。

    设计一种方案,确保页面中所有js加载完全

    function loadScript (url, callback) {
    var script = document.createElement('script')
    script.type = 'text/javascript'
    if (script.readyState) {
    script.onreadystatechange = function () {
    if (script.readyState == 'loaded' || script.readyState == 'complete') {
    script.onreadystatechange = null
    callback()
    }
    }
    } else {
    script.onload = function () {
    callback()
    }
    }
    script.src = url
    document.getElementsByName('head')[0].appendChild(script)
    }

    相关文章

      网友评论

          本文标题:前端知识体系总结

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