上海网站设计建设wordpress文件上传系统

当前位置: 首页 > news >正文

上海网站设计建设,wordpress文件上传系统,免费发布信息的网站平台,wordpress文章编辑函数前言 第一遍看 axios 源码#xff0c;更多的是带着日常开发的习惯#xff0c;时不时产生出点联想。 第二遍再看 axios 源码#xff0c;目标明确#xff0c;就是奔着函数来的。 当有了明确清晰的目标#xff0c;阅读速度上来了#xff0c;思绪也转的飞快。 按图索骥更多的是带着日常开发的习惯时不时产生出点联想。 第二遍再看 axios 源码目标明确就是奔着函数来的。 当有了明确清晰的目标阅读速度上来了思绪也转的飞快。 按图索骥接下来将和大家一起找寻 axios 源码中的功能函数扩展一下开发思路。 文章速读 阅读文章可以有以下收获 功能函数 一般基础的工具函数都会放到 utils.js 文件中。前一篇源码阅读中介绍了关于类型判断的两种方法。 axios 中有许多模块不同的模块下包含不同的功能。除了 utils.js 文件这些模块下的文件也包含函数。我称之为功能函数。 功能函数按照实际功能需要封装的函数也许并不是常见功能需要的但是了解之后没准能帮助今后用到的时候快速完成开发。 1.standardBrowserEnv 标准浏览器中对 cookie 的读写删操作 axios 拥有对 cookie 操作的能力就像叶一一会讲故事一样理所当然。 看源码功能之前我们先来复习关于 cookie 的知识点。 cookie 的格式 通过 document.cookie 获取 cookie 的值是一串有特定格式的字符串。它的格式是 cookie1value; cookie2value; cookie3value; 了解了 cookie 的格式对于它的操作也自然而然的可以接着看代码了。 cookie 的读写删 在标准浏览器中对 cookie 的处理被封装在了一个立即执行函数里。 (function standardBrowserEnv() {return {/** * cookie 写入创建单个写入 * param {string} name cookie 名 * param {string} value cookie 值 * param {*} expires 过期时间 * param {*} path cookie所在的目录 * param {*} domain cookie所在的域 * param {*} secure 是否可以通过HTTP协议的URL设置布尔值 值为 true 时表示创建的 cookie 只能用 HTTPS 协议发送 */ write: function write(name, value, expires, path, domain, secure) { // 先将所有的数据存入数组const cookie [];cookie.push(name encodeURIComponent(value));// 如果过期时间有值且是数值型则存入其转为根据格林威治时间 (GMT) 转成的字符串if (utils.isNumber(expires)) {cookie.push(expires new Date(expires).toGMTString());} // 当目录存在且为字符串则存入cookieif (utils.isString(path)) {cookie.push(path path);}// 当域存在且为字符串则存入cookieif (utils.isString(domain)) {cookie.push(domain domain);}// 是否可以通过HTTP协议的URL设置布尔值为 true 时则存入cookieif (secure true) {cookie.push(secure);} // 将数组转为字符串并通过 document.cookie 属性来创建 cookiedocument.cookie cookie.join(; );},/** * cookie 读取 单个读取 * param {string} name cookie 名 /read: function read(name) { // 正则匹配得到数组const match document.cookie.match(new RegExp((^|;\s)( name )([^;]*))); // match 匹配的返回值中第四个元素为需要的值return match ? decodeURIComponent(match[3]) : null;}, /** * cookie 删除 单个删除 * param {string} name cookie 名 /remove: function remove(name) {// 将过期时间设置为过去的时间即可删除 cookie, 这里设置成了前一天86400000为1天的毫秒数this.write(name, , Date.now() - 86400000);},}; })(); 使用 // 写入 cookies.write(foo, bar); // 删除 cookies.remove(foo); // 读取 cookies.read(usernameJohn Doe) // John Doe 功能汇总 日期转换 toGMTString 方法 toGMTString() 方法可根据格林尼治标准时间 (GMT) 把 Date 对象转换为字符串并返回结果。 介绍这个方法主要科普一个新旧交替的世界标准时间。 首先这个 GMT 和 UTC 的定义如下 GMT(Greenwich Mean Time)格林尼治标准时间。格林尼治是英国伦敦南郊原皇家格林尼治天文台所在地地球本初子午线的标界处世界计算时间和经度的起点。格林尼治标准时间过去被当成世界标准的时间。 UTC(Coordinated Universal Time)协调世界时。又称世界统一时间、世界标准时间、国际协调时间。协调世界时是以原子时秒长为基础在时刻上尽量接近于世界时的一种时间计量系统。协调世界时是现在使用的世界标准时间。 所以在W3C下面有一行提示 不赞成使用此方法。请使用 toUTCString() 取而代之 toUTCString 方法 根据协调世界时 (UTC) 把 Date 对象转换为字符串并返回结果。 正则 match 方法 match() 方法可在字符串内检索指定的值或找到一个或多个正则表达式的匹配。 返回值 它的返回值是一个存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。 如果 regexp 没有标志 g那么 match() 方法就只能在 stringObject 中执行一次匹配。 如果找到匹配结果它将返回一个数组存放了与它找到的匹配文本有关的信息。数组的第1个元素存放的是匹配的文本其余的元素存放与正则表达式的子表达式匹配的文本和input、index、groups三个元素。 如果没找到匹配结果返回 null。 如果 regexp 具有标志 g则 match() 方法将执行全局检索找到 stringObject 中的所有匹配子字符串。 如果找到匹配结果它将返回一个数组数组的第1个元素存放的是匹配的文本其余元素存放匹配的一个或多个文本。* 如果没找到匹配结果返回 null。
小结 1.对 cookie 的读写删操作还是挺简单的主要是参数要考虑全面。日常开发中使用频率不是很高但是如果需求涉及到可以帮助快速完成开发。 2.在 standardBrowserEnv 函数中不难在里面发现 utils 的身影所以基础工具函数的建设必不可少。 3.把 Date 对象转换为字符串推荐使用 toUTCString 方法。 4.无法删除的属性可以设置成无效的值比如这里的通过过期时间提前于当前时间。再比如前一篇介绍过将属性值设置为 undefined。 2.formDataToJSON 抽丝剥茧 formData 与 Object 的转换 FormData 对象 FormData 对象用以将数据编译成键值对以便用XMLHttpRequest来发送数据。 FormData 对象主要用于发送表单数据但亦可用于发送带键数据 (keyed data)而独立于表单使用。一般文件流数据的发送会用到 FormData 对象。 第一条丝线— parsePropPath matchAll matchAll 函数会根据入参的正则表达式和字符串返回所有匹配项的数组。 /*** It takes a regular expression and a string, and returns an array of all the matches** param {string} regExp - The regular expression to match against.* param {string} str - The string to search.** returns {Arrayboolean}/ const matchAll (regExp, str) {let matches;const arr [];// matches 为每次匹配正确的值while ((matches regExp.exec(str)) ! null) {arr.push(matches);}return arr; } regExp.exec 方法 在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。 匹配的标准用法就是如上功能中的那样如果需要进一步了解可以阅读 MDN 文档。 parsePropPath parsePropPath **函数会将字符串中的字母匹配出来放到数组中。 但看描述和函数还不太确定具体用法但是经典的来了。 当我们设计的某个函数不好用文字做描述可以用举例的方式辅助描述。比如下面这个函数不但举例还举了多个例子所以这个函数的用途一目了然。 / It takes a string like foo[x][y][z] and returns an array like [foo, x, y, z]** param {string} name - The name of the property to get.** returns An array of strings./ function parsePropPath(name) {// foo[x][y][z]// foo.x.y.z// foo-x-y-z// foo x y zreturn utils.matchAll(/\w|[(\w)]/g, name).map(match { // 匹配值为数组当匹配的第一个元素为空数组时返回空字符串否则返回第二个元素或第一个元素存在值的那个。return match[0] [] ? : match[1] || match[0];}); } 第二条丝线— arrayToObject arrayToObject 函数会将数组转换对象。 /*** Convert an array to an object.** param {Arrayany} arr - The array to convert to an object.** returns An object with the same keys and values as the array./ function arrayToObject(arr) {const obj {};// 返回数组索引值的数组const keys Object.keys(arr);let i;const len keys.length;let key;for (i 0; i len; i) {key keys[i];obj[key] arr[key];}return obj; } 第三条丝线— forEachEntry forEachEntry 函数会循环一个可迭代的对象直到循环结束把对象的 key 和 value 返回。 /** For each entry in the object, call the function with the key and value.** param {Objectany, any} obj - The object to iterate over.* param {Function} fn - The function to call for each entry.** returns {void}/ const forEachEntry (obj, fn) {const generator obj obj[Symbol.iterator];const iterator generator.call(obj);let result;// 循环直到迭代器已将序列迭代完毕while ((result iterator.next()) !result.done) {const pair result.value;fn.call(obj, pair[0], pair[1]);} }; 我找了一个可迭代对象测试了一下输出 const data new Map();data.set(a, 1); data.set(b, 2); data.set(c, 3);forEachEntry(data, (name, value) {let res name - value;console.log(name-value:, res); });// 输出结果 // name-value: a-1 // name-value: b-2 // name-value: c-3 formDataToJSON formDataToJSON函数接受 一个 FormData 对象最终返回 JavaScript 对象。 /** It takes a FormData object and returns a JavaScript object** param {string} formData The FormData object to convert to JSON.** returns {Objectstring, any | null} The converted object.*/ function formDataToJSON(formData) {/** * 递归函数 将 FormData 的键值全部插入到给 target 对象 * param {Array} path FormData 的属性名数组 * param {string} value FormData 的属性值 * param {Object} target 最终的目标对象 * param {number} index FormData 的属性值数组的索引值 * returns 递归是否中止的布尔值 */function buildPath(path, value, target, index) {let name path[index];// isFinite 函数会先将测试值转换为数字然后再对其进行是否为有限数检测。const isNumericKey Number.isFinite(name);const isLast index path.length;name !name utils.isArray(target) ? target.length : name;if (isLast) {// 如果检查对象具有该属性将 value 添加到对应的数组中if (utils.hasOwnProp(target, name)) {target[name] [target[name], value];} else {target[name] value;}return !isNumericKey;}if (!target[name] || !utils.isObject(target[name])) {target[name] [];}const result buildPath(path, value, target[name], index);if (result utils.isArray(target[name])) {target[name] arrayToObject(target[name]);}return !isNumericKey;}// formData 参数是 FormData 类型且 formData.entries 是一个函数if (utils.isFormData(formData) utils.isFunction(formData.entries)) {const obj {};utils.forEachEntry(formData, (name, value) {buildPath(parsePropPath(name), value, obj, 0);});return obj;}return null; } 我找 axios 自带的测试实例中的例子打印了一下结果 对象的值是数组 const formData new FormData(); formData.append(foo, 1); formData.append(foo, 2);const res formDataToJSON(formData); console.log(res, res); // - { foo: [1, 2] } 对象 const formData new FormData();formData.append(foo, 1); formData.append(bar, 2);const res formDataToJSON(formData); console.log(res, res); // - {foo: 1, bar: 2} 嵌套对象 const formData new FormData();formData.append(foo[bar][baz], 123);const res formDataToJSON(formData); console.log(res, res); // - { foo : { bar : {baz: 123} } } 小结 1.formDataToJSON 函数接受 一个 FormData 对象最终返回 JavaScript 对象。 2.FormData() 构造函数用于创建一个新的FormData对象。该函数在 Web 中可用一些环境会报错“FormData is not define”。 3.FormData 对象转换 JavaScript 对象的功能不是很常用。但是这里的主要收获是当函数设计的相对复杂的时候可以用抽丝剥茧的方式现将支线整理出来最终拼凑成一个完整的主线。 总结 功能函数会依据实际需求去实现功能。通过分析 axios 源码中的两个重点的功能函数学习复杂功能如何设计以及补充了些知识点还得到目前代码中有些判断条件简化的收获。 很愉快的一次源码阅读体验。 axios 源码阅读历程 捎带分享一下我关于 axios 源码阅读中的历程。 数月前 因为工作中需要弄清楚 axios 的 request 中的入参而在源码中寻找答案当时想抽时间进行一次源码阅读但是没有坚持下去就此作罢。 数日前 前几天做功能联想重新开始阅读这次收获颇多。 最后 最近找到一个VUE的文档它将VUE的各个知识点进行了总结整理成了《Vue 开发必须知道的36个技巧》。内容比较详实对各个知识点的讲解也十分到位。 有需要的小伙伴可以点击下方卡片领取无偿分享