正文
return cloneTarget } else { return target } } #####自定义instanceof工具函数 /* 自定义instanceof工具函数: 语法: myInstanceOf(obj, Type) 功能: 判断obj是否是Type类型的实例 实现: Type的原型对象是否是obj的原型链上的某个对象, 如果是返回true, 否则返回false */ export function myInstanceOf(obj, Type) { // 得到原型对象 let protoObj = obj.proto // 只要原型对象存在 while(protoObj) { // 如果原型对象是Type的原型对象, 返回true if (protoObj === Type.prototype) { return true } // 指定原型对象的原型对象 protoObj = protoObj.proto } return false } #####自定义new工具函数 /* 自定义new工具函数 语法: newInstance(Fn, …args) 功能: 创建Fn构造函数的实例对象 实现: 创建空对象obj, 调用Fn指定this为obj, 返回obj */ export function newInstance(Fn, …args) { // 创建一个新的对象 const obj = {} // 执行构造函数 const result = Fn.apply(obj, args) // 相当于: obj.Fn() // 如果构造函数执行的结果是对象, 返回这个对象 if (result instanceof Object) { return result } // 如果不是, 返回新创建的对象 obj.proto.constructor = Fn // 让原型对象的构造器属性指向Fn return obj } #####手写axios函数 /* 1. 函数的返回值为promise, 成功的结果为response, 失败的结果为error 2. 能处理多种类型的请求: GET/POST/PUT/DELETE 3. 函数的参数为一个配置对象 { url: ‘’, // 请求地址 method: ‘’, // 请求方式GET/POST/PUT/DELETE params: {}, // GET/DELETE请求的query参数 data: {}, // POST或DELETE请求的请求体参数 } 4. 响应json数据自动解析为js的对象/数组 / / 发送任意类型请求的函数 / function axios({ url, method=‘GET’, params={}, data={} }) { // 返回一个promise对象 return new Promise((resolve, reject) => { // 处理method(转大写) method = method.toUpperCase() // 处理query参数(拼接到url上) id=1&xxx=abc / { id: 1, xxx: ‘abc’ } / let queryString = ‘’ Object.keys(params).forEach(key => { queryString += ${key}=${params[key]}& }) if (queryString) { // id=1&xxx=abc& // 去除最后的& queryString = queryString.substring(0, queryString.length-1) // 接到url url += ‘?’ + queryString } // 1. 执行异步ajax请求 // 创建xhr对象 const request = new XMLHttpRequest() // 打开连接(初始化请求, 没有请求) request.open(method, url, true) // 发送请求 if (method===‘GET’) { request.send() } else if (method===‘POST’ || method===‘PUT’ || method===‘DELETE’){ request.setRequestHeader(‘Content-Type’, ‘application/json;charset=utf-8’) // 告诉服务器请求体的格式是json request.send(JSON.stringify(data)) // 发送json格式请求体参数 } // 绑定状态改变的监听 request.onreadystatechange = function () { // 如果请求没有完成, 直接结束 if (request.readyState!==4) { return } // 如果响应状态码在[200, 300)之间代表成功, 否则失败 const {status, statusText} = request // 2.1. 如果请求成功了, 调用resolve() if (status>=200 && status<=299) { // 准备结果数据对象response const response = { data: JSON.parse(request.response), status, statusText } resolve(response) } else { // 2.2. 如果请求失败了, 调用reject() reject(new Error('request error status is ’ + status)) } } }) } / 发送特定请求的静态方法 */ axios.get = function (url, options) { return axios(Object.assign(options, {url, method: ‘GET’})) } axios.delete = function (url, options) { return axios(Object.assign(options, {url, method: ‘DELETE’})) } axios.post = function (url, data, options) { return axios(Object.assign(options, {url, data, method: ‘POST’})) } axios.put = function (url, data, options) { return axios(Object.assign(options, {url, data, method: ‘PUT’})) } export default axios #####自定义事件总线 /* • 自定义事件总线 / const eventBus = {} / { add: [callback1, callback2] delete: [callback3] } / let callbacksObj = {} / 绑定事件监听 / eventBus.on = function (eventName, callback) { const callbacks = callbacksObj[eventName] if (callbacks) { callbacks.push(callback) } else { callbacksObj[eventName] = [callback] } } / 分发事件 / eventBus.emit = function (eventName, data) { const callbacks = callbacksObj[eventName] if (callbacks && callbacks.length > 0) { callbacks.forEach(callback => { callback(data) }) } } / 移除事件监听 */ eventBus.off = function (eventName) { if (eventName) { delete callbacksObj[eventName] } else { callbacksObj = {} } } export default eventBus #####自定义消息订阅与发布 /* 自定义消息订阅与发布 / const PubSub = {} / { add: { token1: callback1, token2: callback2 }, update: { token3: callback3 } } / let callbacksObj = {} // 保存所有回调的容器 let id = 0 // 用于生成token的标记 // 1. 订阅消息 PubSub.subscribe = function (msgName, callback) { // 确定token const token = ‘token_’ + ++id // 取出当前消息对应的callbacks const callbacks = callbacksObj[msgName] if (!callbacks) { callbacksObj[msgName] = { [token]: callback } } else { callbacks[token] = callback } // 返回token return token } // 2. 发布异步的消息 PubSub.publish = function (msgName, data) { // 取出当前消息对应的callbacks let callbacks = callbacksObj[msgName] // 如果有值 if (callbacks) { // callbacks = Object.assign({}, callbacks) // 启动定时器, 异步执行所有的回调函数 setTimeout(() => { Object.values(callbacks).forEach(callback => { callback(data) }) }, 0) } } // 3. 发布同步的消息 PubSub.publishSync = function (msgName, data) { // 取出当前消息对应的callbacks const callbacks = callbacksObj[msgName] // 如果有值 if (callbacks) { // 立即同步执行所有的回调函数 Object.values(callbacks).forEach(callback => { callback(data) }) } } / 4. 取消消息订阅 1). 没有传值, flag为undefined 2). 传入token字符串 3). msgName字符串 */ PubSub.unsubscribe = function (flag) { // 如果flag没有指定或者为null, 取消所有 if (flag === undefined) { callbacksObj = {} } else if (typeof flag === ‘string’) { if (flag.indexOf(‘token_’) === 0) { // flag是token // 找到flag对应的callbacks const callbacks = Object.values(callbacksObj).find(callbacks => callbacks.hasOwnProperty(flag)) // 如果存在, 删除对应的属性 if (callbacks) { delete callbacks[flag] } } else { // flag是msgName delete callbacksObj[flag] } } else { throw new Error(‘如果传入参数, 必须是字符串类型’) } } export default PubSub #####自定义数组声明式系列方法 /* 实现数组声明式处理系列工具函数 / / 实现map() / export function map (array, callback) { const arr = [] for (let index = 0; index < array.length; index++) { arr.push(callback(array[index], index)) } return arr } / 实现reduce() / export function reduce (array, callback, initValue) { let result = initValue for (let index = 0; index < array.length; index++) { // 调用回调函数将返回的结果赋值给result result = callback(result, array[index], index) } return result } / 实现filter() / export function filter(array, callback) { const arr = [] for (let index = 0; index < array.length; index++) { if (callback(array[index], index)) { arr.push(array[index]) } } return arr } / 实现find() / export function find (array, callback) { for (let index = 0; index < array.length; index++) { if (callback(array[index], index)) { return array[index] } } return undefined } / 实现findIndex() / export function findIndex (array, callback) { for (let index = 0; index < array.length; index++) { if (callback(array[index], index)) { return index } } return -1 } / 实现every() / export function every (array, callback) { for (let index = 0; index < array.length; index++) { if (!callback(array[index], index)) { // 只有一个结果为false, 直接返回false return false } } return true } / 实现some() */ export function some (array, callback) { for (let index = 0; index < array.length; index++) { if (callback(array[index], index)) { // 只有一个结果为true, 直接返回true return true } } return false } export function test() { console.log(‘test()222’) } #####手写Promise const PENDING = ‘pending’ // 初始未确定的状态 const RESOLVED = ‘resolved’ // 成功的状态 const REJECTED = ‘rejected’ // 失败的状态 /* Promise构造函数 / function Promise(excutor) { const self = this // Promise的实例对象 self.status = PENDING // 状态属性, 初始值为pending, 代表初始未确定的状态 self.data = undefined // 用来存储结果数据的属性, 初始值为undefined self.callbacks = [] // {onResolved(){}, onRejected(){}} / 将promise的状态改为成功, 指定成功的value / function resolve(value) { // 如果当前不是pending, 直接结束 if (self.status !== PENDING) return self.status = RESOLVED // 将状态改为成功 self.data = value // 保存成功的value // 异步调用所有缓存的待执行成功的回调函数 if (self.callbacks.length > 0) { // 启动一个延迟时间为0的定时器, 在定时器的回调中执行所有成功的回调 setTimeout(() => { self.callbacks.forEach(cbsObj => { cbsObj.onResolved(value) }) }) } } / 将promise的状态改为失败, 指定失败的reason / function reject(reason) { // 如果当前不是pending, 直接结束 if (self.status !== PENDING) return self.status = REJECTED // 将状态改为失败 self.data = reason // 保存reason数据 // 异步调用所有缓存的待执行失败的回调函数 if (self.callbacks.length > 0) { // 启动一个延迟时间为0的定时器, 在定时器的回调中执行所有失败的回调 setTimeout(() => { self.callbacks.forEach(cbsObj => { cbsObj.onRejected(reason) }) }) } } // 调用excutor来启动异步任务 try { excutor(resolve, reject) } catch (error) { // 执行器执行出错, 当前promise变为失败 console.log(‘-----’) reject(error) } } / 用来指定成功/失败回调函数的方法 1). 如果当前promise是resolved, 异步执行成功的回调函数onResolved 2). 如果当前promise是rejected, 异步执行成功的回调函数onRejected 3). 如果当前promise是pending, 保存回调函数 返回一个新的promise对象 它的结果状态由onResolved或者onRejected执行的结果决定 2.1). 抛出error ==> 变为rejected, 结果值为error 2.2). 返回值不是promise ==> 变为resolved, 结果值为返回值 2.3). 返回值是promise ===> 由这个promise的决定新的promise的结果(成功/失败) / Promise.prototype.then = function (onResolved, onRejected) { const self = this onResolved = typeof onResolved === ‘function’ ? onResolved : value => value // 将value向下传递 onRejected = typeof onRejected === ‘function’ ? onRejected : reason => { throw reason } // 将reason向下传递 return new Promise((resolve, reject) => { // 什么时候改变它的状态 / 1. 调用指定的回调函数 2. 根据回调执行结果来更新返回promise的状态 / function handle(callback) { try { const result = callback(self.data) if (!(result instanceof Promise)) { // 2.2). 返回值不是promise ==> 变为resolved, 结果值为返回值 resolve(result) } else { // 2.3). 返回值是promise ===> 由这个promise的决定新的promise的结果(成功/失败) result.then( value => resolve(value), reason => reject(reason) ) // result.then(resolve, reject) } } catch (error) { // 2.1). 抛出error ==> 变为rejected, 结果值为error reject(error) } } if (self.status === RESOLVED) { setTimeout(() => { handle(onResolved) }) } else if (self.status === REJECTED) { setTimeout(() => { handle(onRejected) }) } else { // PENDING self.callbacks.push({ onResolved(value) { handle(onResolved) }, onRejected(reason) { handle(onRejected) } }) } }) } / 用来指定失败回调函数的方法 catch是then的语法糖 / Promise.prototype.catch = function (onRejected) { return this.then(undefined, onRejected) } / 用来返回一个指定vlaue的成功的promise value可能是一个一般的值, 也可能是promise对象 */ Promise.resolve = function (value) { return new Promise((resolve, reject) => {
最后
javascript是前端必要掌握的真正算得上是编程语言的语言,学会灵活运用javascript,将对以后学习工作有非常大的帮助。掌握它最重要的首先是学习好基础知识,而后通过不断的实战来提升我们的编程技巧和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。