jQuery源码分析
(function (global, factory) {"use strict"/*global:在浏览器&webpack环境下,global是window,在Node环境下,global是Global全局对象/模块factory:传递的callback*/if (typeof module === "object" && typeof module.exports === "object") {// JQ代码是在支持CommonJS规范「Node&Webpack」的环境下运行module.exports = global.document ?// 在webpack环境下运行:把 factory 执行的结果,基于 module.exports 导出// --> module.exports = jQuery// --> const $ = require('jquery') $就是导出的这个jQuery函数factory(global, true) :// 在Node环境下运行:JQ是不支持在Node环境下运行的// --> const $ = require('jquery')// --> $('box')function (w) {if (!w.document) {throw new Error("jQuery requires a window with a document");}return factory(w);}} else {// 在浏览器端运行:把factory执行// --> <script src='js/jquery.min.js'>factory(global)}})(typeof window !== "undefined" ? window : this,//这里可看下图 node环境下无window//==========================================↗↗↗↗↗↗↑↑↑↑↑↑↑↑↑↑↑↑↑↖↖↖↖↖↖↖function (window, noGlobal) {/*进入这里只有两种情况:1. 在浏览器下运行window->window对象noGlobal->undefined2. 在webpack下运行window->window对象noGlobal->true*/"use strict"/* 构造函数 */var jQuery = function (selector, context) {return new jQuery.fn.init(selector, context)}jQuery.fn = jQuery.prototype = {constructor: jQuery,// ...}var init = jQuery.fn.init = function (selector, context, root) {// ...}init.prototype = jQuery.fn/*$() / jQuery() -> 创造 jQuery 类的实例「可以调用 jQuery.prototype 上提供的属性方法」问题:它是如何做到,把函数当做普通函数执行(没有带new),最后还创建了自己这个类的一个实例?它用到了“工厂设计模式「中转类」”+ $() 首次创建的是 init 这个类的一个实例+ init.prototype = jQuery.prototype+ 创建的实例就相当于 jQuery 类的实例*//* 暴露API */// 对AMD模块化思想的支持if (typeof define === "function" && define.amd) {define("jquery", [], function () {return jQuery})}// 在浏览器下运行if (typeof noGlobal === "undefined") {window.jQuery = window.$ = jQuery}// 支持 webpack 基于 module.exports 导出return jQuery})/*let arr = [10, 20, 30]arr.push(40)console.log(arr)*/const push = [].push // Array.prototype.pushlet arr = [10, 20, 30]push.call(arr, 40)

![{29FR$UYHZZ5K1(F}LDI3B_tmb.jpg
仿照jQuery源码处理utils.js文件
(function (global, factory) {"use strict"if (typeof module === 'object' && typeof module.exports === 'object') {//node or webpack environmentsmodule.exports = factory(global, true)return}//browser environmentsfactory(global)})(typeof window !== "undefined" ? window : this,function factory(window, noGlobal) {"use strict"//检测是否为函数const isFunction = function isFunction(obj) {return typeof obj === 'function'}//笼统校验是否为对象const isObject = function isObject(obj) {return obj !== null && /^(object|function)$/.test(typeof obj)}// 获取对象所有私有成员「兼容到IE、不受枚举和类型的限制」const ownKeys = function ownKeys(obj) {if (!isObject(obj)) throw new TypeError('传递的obj不是一个对象')let keys = Object.getOwnPropertyNames(obj)if (typeof Symbol !== 'undefined') {keys = keys.concat(Object.getOwnPropertySymbols(obj))}return keys}//给对象新增一个不可枚举的成员(可删除可修改)const def = function define(obj, key, value) {Object.defineProperty(obj, key, {value,//"value":value | value:valuewritable: true,configurable: true,enumerable: false})}/* 暴露API */const utils = {isFunction,isObject,ownKeys,def}if (typeof define === "function" && define.amd) {define("utils", [], function () {return utils})}if (typeof noGlobal === "undefined") {window.utils = window._ = utils}return utils})//检测是否为函数const isFunction = function isFunction(obj) {return typeof obj === 'function'}//笼统校验是否为对象const isObject = function isObject(obj) {return obj !== null && /^(object|function)$/.test(typeof obj)}//获取对象所有私有成员(兼容IE、不受枚举和类型限制)/* const ownKeys = function ownKeys(obj) {// 确保传递的是对象if (!isObject(obj)) throw new TypeError('传递的obj不是一个对象')// 验证是否支持Reflectif (typeof Reflect !== 'undefined') return Reflect.ownKeys(obj)return Object.getOwnPropertyNames(obj)} */// 获取对象所有私有成员「兼容到IE、不受枚举和类型的限制」const ownKeys = function ownKeys(obj) {if (!isObject(obj)) throw new TypeError('传递的obj不是一个对象')let keys = Object.getOwnPropertyNames(obj)if (typeof Symbol !== 'undefined') {keys = keys.concat(Object.getOwnPropertySymbols(obj))}return keys}//给对象新增一个不可枚举的成员(可删除可修改)const def = function define(obj, key, value) {Object.defineProperty(obj, key, {value,//"value":value | value:valuewritable: true,configurable: true,enumerable: false})}




