# 分析源码学架构
#
# 读源码技巧
- 不要试图一句一句读下去
- 先理架构,再看入口,依流程读下去
# 读源码能给我们带来什么?
- 优秀的架构和设计思维
- 对于所用工具有更深的理解
- 优秀的使用技巧
# jquery架构分析
- 没有模块化时代的一个典型的架构代表
# 架构特点
- 利用工厂模式,无new化构建对象
- 模块划分明确
- 开闭原则的优秀体现
# jquery技巧提炼
- 优秀的参数处理(多态,健壮性)
- 多态,可以支持多种参数
- 健壮性,防止忘记传参数或者传错参数,导致报错
- 模块化支持的检测
# 无模块化时代模块封装特点
- 工具库或者类似jquery这样的单页面的库
- 最外层是一个匿名自执行函数
- 然后将window和undefined作为参数传入
- js变量查找,有一个作用域链,优先在当前作用域查找,找不到的话, 会沿作用域链,逐级向上查找
- 传入window,可以减少逐级向上查找的时间
- undefined对于js来说,它是一个变量,而不是一个关键字,而null是一个关键字,所以不传null
- 暴露的jquery并不是jquery的实例化对象,而是一个工厂模式的工厂方法, 而vue是直接把类暴露出去了
- 这跟应用场景有关系,vue中有且只有一个根实例,全局只有一个new Vue()对象,其他的都是该对象的组件,所以vue需要对外暴露一个类
- 工厂模式,本身是一个方法, 我调用这个方法,告诉这个方法我需要什么东西,这个方法把你要的东西给出来
- 建立一个工厂方法,你只需要告诉这个工厂你要什么,他就会给你什么
- 工厂方法特别适合于快速创建大量对象的情况,而jquery需要大量的创建DOM对象,所以用工厂模式更合适
- 利用js引用类型的特点 jquery.prototype = jquery.prototype.init.prototype = jquery.fn 把这三个都指向jquery.prototype对象, 这样做修改时,只需要修改jquery.prototype对象即可,做到共享原型的效果
- jquery的模块划分,是先实现一个extends工具方法,然后把很多功能划分为很多模块, 然后每个模块都作为一个单独的对象,通过extends方法将各个模块扩展进去,而不是一股脑的把模块方法挂载到jquery.prototype对象上,这样做不仅干净优雅 ,而且方便后期修改维护, 同时通过extends方法提供给我们一个扩展方法,既考虑到本身的模块化,又考虑到后期的修改和扩展
- 享元模式,目的:减少对象数量,做法:把这些对象分析,分析出私有的数据和方法,分析出公用的数据和方法
- 容错处理,是一种代码健壮性的体现,防止错误使用出现问题
- 模块化支持的检测
(function(window, undefined){ function jQuery(selector){ return new jQuery(selector) // 这样会造成循环调用,不对 return new jQuery.fn.init() //正确做法,无new化构建对象 } jQuery.prototype = { init: function(){ } } // 享元模式 jQuery.extends = function(){ var target = arguments[0] || {} var length = arguments.length var i = 1 if(target!=='object'){ target = {} } if(length === 1){ target = this i-- } for(var item in arguments[i]){ target[item] = arguments[i][item] } } jQuery.prototype = jQuery.prototype.init.prototype = jQuery.fn // 利用js引用类型的特点,共享原型 // 把这三个都指向jQuery.prototype对象, 这样做修改时,只需要修改jQuery.prototype对象即可,做到共享原型的效果 window.jQuery = jQuery window.$ = jQuery // 模块化支持的检测 if(typeof define === 'function' && define.amd && define.amd.jQuery){ define('jquery', [], function(){ return jQuery }) //通过amd的规范把jquery暴露出来 } })(window,undefined)
// vue中的模块化检测 // commonJS支持和amd支持 (function(global, factory){ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.Vue = factory()) })(this, function(){ 'use strict' })