美文网首页
2020-03-09 分析源码学架构--那些源码教我的事

2020-03-09 分析源码学架构--那些源码教我的事

作者: 哎哟码呀 | 来源:发表于2020-03-18 18:19 被阅读0次

    PPT的开始

    1

    一、如何分析源码:

    分析源码
    源码能给我们带来什么?
    优秀的架构设计思维:

    注意框架设计思维,如vue响应式的思维,如何设计,如何模仿搭建架构。

    对于所用工具更深的理解

    通过阅读源码,对工具理解更深,帮助我们更好的使用工具。

    优秀的技巧

    通过看源码,学习优秀的技巧,优秀的框架,代码的质量必然很高,掌握别人如何去写的,哪里写得好。

    二、源码都有的特性

    开始时会出现大量的健壮的处理:if else 的判断,阅读时大部分可以忽略掉。

    健壮事例:
    //不够健壮的代码
    function add(a,b){
        return a+b;
    }
    
    function add(a,b){
        if(! typeof a == 'number'){
          a =0;
        }
        return a+b;
    }
    //健壮性最有效的保证就是在参数层面去判断
    
    健壮性事例:

    Node中读取文件,但是文件可能不存在,如果不处理,可能就会报错,Node是服务,那么一定是持久的,如果不加判断,可能这个异常会导致服务的停止。那么我们如何去增强其健壮性?

    try{//把容易出问题的代码用 try 包裹起来
      fs.readFile('xxx');
    }catch(e){
      console.log(e);
    }
    

    其他源码的事例:


    多判断
    读源码规则:

    源码往往是模块调用模块
    不要试图一句一句的读源码
    先理架构,在看入口,按流程读下去
    摒弃其他代码,寻找核心代码

    经典框架都是什么样的套路

    分别有工厂模式,建造者模式,函数式;

    (1)工厂模式 ----> 给一个批量对象的工厂,来帮助你获取对象
    应用场景:你的框架,插件,需要大量的产出对象时
    举例:jquery
    如果每一次使用的话 都用new $()是不是特别繁琐,所以 jquery没有new,而是使用$. 或者$('xxx'). 的形式
    举例:弹窗插件
    页面中也会经常用到,如果每次都去new PopWindow()也是很繁琐的,最好的使用方式就是通过PopWindow.Show()的方式。

    (2)建造者模式 ----> 构造比较复杂,产生的东西不多,一个页面只有一个的情况下
    例如:好比建造房子,不可能从头到尾原材料加工,而是钢筋,砖瓦一起拼接到一起的来建造房子的。

    举例:

    function banner(){
      this.htmlInit = new htmlInit();
      this.runner = new runner();
    } 
    function htmlInit(){}
    function runner(){}
    

    举例:
    vue 利用的建造者模式

    函数式编程:
    loadsh,都是函数式编程。

    疑问:为什么VUE3 又变回函数式?
    (1)、组合大于继承,
    优点:组合扩展性更好,继承的话 还要修改其他父类子类。
    缺点:需要再次调用,重复写方法的名字。
    !!! 重要:能用组合的不要用继承来解决。

    function a(){}
    function b(){}
    function c(){
      a();
      b();
    }
    

    (2)、为了使用tree-shaking库
    如果这个库有100个方法,但是你只用到2个方法,那么用tree-shaking,他只会帮你把这两个方法打包进去。
    但是tree-shaking只会对函数有效,无法对对象进行操作shaking。

    (3)、压缩的时候,独立的方法压缩的更简单
    如:

    function add(){}
    压缩成
    _a(){}
    

    三、手写jQuery。

    (function(window){
      function jquery(seletor){
        return new jquery.fn.init(seletor);
      }
      jquery.fn.init.prototype=jquery.fn;
      jquery.fn = jquery.prototype={
        init:function(){
    
        }
      }
      jquery.extend = jquery.fn.extend = function(){
        //前提:这个方法可能会传1个参数,也可能传两个,如何优化?
        //不规范的写法
        if(arguments.lenght == 1){
          for(var item in arguments[0]){
            this[item] = arguments[0][item]//{a:1}  ==> a = 1
          }
        }else{
           for(var item in arguments[1]){
            arguments[0][item] = arguments[1][item]
          }
        }
    
        //规范写法:享元模式的写法:拿出不同的,保留相同的。
        var target = arguments[0]||{};
        var options;
        var i = 1;
        if(arguments.length == 1){
          target = this;
          i--;
        }
        options = arguments[i];//如果只有1个,那么i0,这时候拿的是第一个参数
    
         for(var name in options){
            target[name] = options[name]
        }
      }
    
      jquery.fn.extend({
          //CSS 模块会扩展在这里面
      })
      
     jquery.fn.extend({
          //动画模块扩展
      })
    
    //模块化检测的,插件,模块,建议大家都去加入这个判断 amd ,cmd;
      if(typeof define === "function" && define.amd && define.amd.jQuery) {
          define( "jquery",[],function(){ return jQuery });
      }
    
      window.jquery = window.$=jquery;
    })(window)
    

    疑问:为什么jquery每个方法都需要传递window?

    答案:是因为减少查找,提高性能,javaScript查找window对象的时候,会先从当前层级一步步往外查询,如果发现当前层级有window,那么就可以直接使用,如果没有继续向上一层查找,直到找到最外层window为止。
    我们这儿window传进来,则不会去向外查找,解决性能上的优化,减少查找时间。

    vue 源码初始化的模块化的判断
    (function (global,factory){
      typeof exports === 'object' && typeof module !== 'undefined' 
              ?
               module.exports = factory()
               :
               type define === 'function' && define.amd 
                    ?
                     define(factory) 
                     : 
                     (global = global || self,global.Vue = factory());
    }(
      this.,function(){
        .....
      }  
    ))
    
    

    检测当前使用的是什么规范,再使用当前有的规范去初始化

    四、Express 部分源码

    举例,如果app对象上面有很多方法,应该怎么写最简洁

    const http = require('http');
    var app = module.exports={}
    app.handle = function(req,res){
      res.end('hello');
    }
    //错误写法
    app.post = {
    
    }
    app.get = {
    
    }
    app.put = {
    
    }
    ......
    
    //靠谱点的写法 ,用桥接模式
    var methods=['put','get','post','delete'];
    methods.forEach((method)=>{
      app[method]=function(){
        router[method].call(this);//在通过路由去分发他们要做的事情
      }
    })
    
    

    相关文章

      网友评论

          本文标题:2020-03-09 分析源码学架构--那些源码教我的事

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