工厂模式
工厂模式
工厂模式即对创建对象逻辑的封装,或者可以简单理解为对new的封装,这种封装就像创建对象的工厂,故名工厂模式。工厂模式常见于大型项目,比如JQ的$对象,我们创建选择器对象时之所以没有new selector就是因为$()已经是一个工厂方法,其他例子例如React.createElement()、Vue.component()都是工厂模式的实现。工厂模式有多种:简单工厂模式、工厂方法模式、抽象工厂模式,这里只以简单工厂模式为例:
1234567891011121314151617181920//循环不变式 guess 等于l r中间位置class User { constructor(name, auth) { this.name = name this.auth = auth }}class UserFactory { static createUser(name, auth) { //工厂内部封装了创建对象的逻辑: //权限为admin时,auth=1, 权限为user时, auth为 ...
迭代+展开运算符
迭代+展开运算符12345678// 每次while都会合并一层的元素,这里第一次合并结果为[1, 1, 2, 1, 2, 3, [4,4,4]]// 然后arr.some判定数组中是否存在数组,因为存在[4,4,4],继续进入第二次循环进行合并let arr = [1, [1,2], [1,2,3,[4,4,4]]]while (arr.some(Array.isArray)) { arr = [].concat(...arr);}console.log(arr) // [1, 1, 2, 1, 2, 3, 4, 4, 4]
解构
解构123456789101112131415161718192021222324// 将 destructuringArray([1, [2, 3], 4], "[a, [b], c]") => {a: 1, b: 2, c: 4}const targetArray = [1, [2, 3], 4];const formater = "[a, [b], c]";const destructuringArray = (values, keys) => { try { const obj = {}; if (typeof keys === 'string') { keys = JSON.parse(keys.replace(/\w+/g, '"$&"')); } const iterate = (values, keys) => k ...
深度拷贝兼容写法(不包括原型属性)
深度拷贝兼容写法(不包括原型属性)123456789101112131415161718function deepCopy(obj) { if (typeof obj !== 'object') return obj; if (typeof window !== 'undefined' && window.JSON) { // 浏览器环境下 并支持window.JSON 则使用 JSON return JSON.parse(JSON.stringify(obj)); } else { let newObj = obj.constructor === Array ? [] : {}; for(let key in obj) { newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj ...
如何主动中止Promise调用链
如何主动中止Promise调用链1234567891011121314151617181920const p1 = new Promise((resolve, reject) => { setTimeout(() => { // 异步操作 resolve('start') }, 1000);});p1.then((result) => { console.log('a', result); return Promise.reject('中断后续调用'); // 此时rejected的状态将直接跳到catch里,剩下的调用不会再继续}).then(result => { console.log('b', result);}).then(result => { console.log('c', result);}).catch(er ...
模板编译
模板编译1234567891011121314151617181920const template = ` <div class="play" name="{{name}}">{{ value }}</div>`const data = { name: 'Brolly', value: 'FE'}const compiler = (str, data) => { const reg = /\{\{(.*?)\}\}/g return str.replace(reg, (patten, g1) => { const key = g1.trim() return data[key] ? data[key] : '' })}const content = c ...
字符串repeat实现
字符串repeat实现1234567891011121314// 原生repeat'ni'.repeat(3); // 'ninini'// 实现一String.prototype.repeatString1 = function (n) { return Array(n + 1).join(this);}console.log('ni'.repeatString1(3));// 实现二String.prototype.repeatString2 = function (n) { return Array(n).fill(this).join('');}console.log('ni'.repeatString2(3));
数组中找出两项相加后的和为num的索引位置
数组中找出两项相加后的和为num的索引位置123456789101112131415function fn(num = 0, ary = []) { for (let i = 0; i < ary.length; i++) { let diff = num - ary[i]; let diffIndex = ary.indexOf(diff); if (diffIndex !== -1 && diffIndex !== i) { return [i, diffIndex]; } } return false;}let num = 3;let arr = [-1, 4, 6, 2];console.log(fn(num, arr)); // [0, 1]
价格区间指定递增
价格区间指定递增
根据指定的价格范围,递增单位也不同。在 0 到 10 之间,每次递增 1;在 10 到 100 之间,每次递增 5;在 100 到 1000 之间,每次递增 10;在 1000 以上,每次递增 20。最小值为 0,最大值等于指定值(如 500)。
123456789101112131415161718192021222324252627282930313233// 这个函数接受一个最大价格作为参数,并返回从0到最大价格之间的所有可能的价格值。该函数将使用一个// 包含每个范围的对象数组,然后使用while循环来生成递增的价格列表。最终的结果将作为数组返回并输出到控制台。// 版本一function getPriceRangeValues(maxPrice) { if (maxPrice == undefined) return [] const priceRanges = [ { max: 10, increment: 1 }, { max: 100, increment: 5 }, { ...
二分查找
二分查找1234567891011121314151617//循环不变式 guess 等于l r中间位置const bsearch = (A, x) => { let l = 0 let r = A.length - 1 let guess while (l <= r) { console.log('find') guess = Math.floor((l + r) / 2) if (A[guess] === x) return guess if (A[guess] > x) r = guess - 1 else l = guess + 1 } return -1}let arr = [1, 2, 3, 4, 5, 6, 7, 8]console.log(bsearch(arr, 6)) // 5