Array篇
定义一个测试数组
1 2 3 4 5 6 7 | const players = [ { name: '科比' , num: 24 }, { name: '詹姆斯' , num: 23 }, { name: '保罗' , num: 3 }, { name: '威少' , num: 0 }, { name: '杜兰特' , num: 35 } ] |
1、forEach
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Array.prototype.sx_forEach = function (callback) { for ( let i = 0; i < this .length; i++) { callback( this [i], i, this ) } } players.sx_forEach((item, index, arr) => { console.log(item, index) }) // { name: '科比', num: 24 } 0 // { name: '詹姆斯', num: 23 } 1 // { name: '保罗', num: 3 } 2 // { name: '威少', num: 0 } 3 // { name: '杜兰特', num: 35 } 4 |
2、map
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 | Array.prototype.sx_map = function (callback) { const res = [] for ( let i = 0; i < this .length; i++) { res.push(callback( this [i], i, this )) } return res } console.log(players.sx_map((item, index) => `${item.name}--${item.num}--${index}`)) // [ '科比--24--0', '詹姆斯--23--1', '保罗--3--2', '威少--0--3', '杜兰特--35--4' ] |
3、filter
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Array.prototype.sx_filter = function (callback) { const res = [] for ( let i = 0; i < this .length; i++) { callback( this [i], i, this ) && res.push( this [i]) } return res } console.log(players.sx_filter(item => item.num >= 23)) // [ // { name: '科比', num: 24 }, // { name: '詹姆斯', num: 23 }, // { name: '杜兰特', num: 35 } // ] |
4、every
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 12 | Array.prototype.sx_every = function (callback) { let flag = true for ( let i = 0; i < this .length; i++) { flag = callback( this [i], i, this ) if (!flag) break } return flag } console.log(players.sx_every(item => item.num >= 23)) // false console.log(players.sx_every(item => item.num >= 0)) // true |
5、some
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 12 | Array.prototype.sx_some = function (callback) { let flag = false for ( let i = 0; i < this .length; i++) { flag = callback( this [i], i, this ) if (flag) break } return flag } console.log(players.sx_some(item => item.num >= 23)) // true console.log(players.sx_some(item => item.num >= 50)) // false |
6、reduce
参数代表含义
- pre:前一项
- next:下一项
- index:当前索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 12 13 | Array.prototype.sx_reduce = function (callback, initValue) { let pre = initValue for ( let i = 0; i < this .length; i++) { pre = callback(pre, this [i], i, this ) } return pre } // 计算所有num相加 const sum = players.sx_reduce((pre, next) => { return pre + next.num }, 0) console.log(sum) // 85 |
7、findIndex
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 | Array.prototype.sx_findIndex = function (callback) { for ( let i = 0; i < this .length; i++) { if (callback( this [i], i, this )) { return i } } return -1 } console.log(players.sx_findIndex(item => item.name === '科比' )) // 0 console.log(players.sx_findIndex(item => item.name === '安东尼' )) // -1 |
8、find
参数代表含义
- item:遍历项
- index:遍历项的索引
- arr:数组本身
1 2 3 4 5 6 7 8 9 10 11 | Array.prototype.sx_find = function (callback) { for ( let i = 0; i < this .length; i++) { if (callback( this [i], i, this )) { return this [i] } } return undefined } console.log(players.sx_find(item => item.name === '科比' )) // { name: '科比', num: 24 } console.log(players.sx_find(item => item.name === '安东尼' )) // undefined |
9、fill
用处:填充数组
参数代表含义
- initValue:填充的值
- start:开始填充索引,默认0
- end:结束填充索引,默认length - 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Array.prototype.sx_fill = function (value, start = 0, end) { end = (end || this .length - 1) + 1 for ( let i = start; i < end; i++) { this [i] = value } return this } console.log(players.sx_fill( '林三心' , 1, 3)) // [ // { name: '科比', num: 24 }, // '林三心', // '林三心', // '林三心', // { name: '杜兰特', num: 35 } // ] |
10、includes
用处:查找元素,查到返回true
,反之返回false
,可查找NaN
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Array.prototype.sx_includes = function (value, start = 0) { if (start < 0) start = this .length + start const isNaN = Number.isNaN(value) for ( let i = start; i < this .length; i++) { if ( this [i] === value || Number.isNaN( this [i]) === isNaN) { return true } } return false } console.log([1, 2, 3].sx_includes(2)) // true console.log([1, 2, 3, NaN].sx_includes(NaN)) // true console.log([1, 2, 3].sx_includes(1, 1)) // false |
11、join
用处:将数组用分隔符拼成字符串,分隔符默认为,
1 2 3 4 5 6 7 8 9 10 | Array.prototype.sx_join = function (s = ',' ) { let str = '' for ( let i = 0; i < this .length; i++) { str = i === 0 ? `${str}${ this [i]}` : `${str}${s}${ this [i]}` } return str } console.log([1, 2, 3].sx_join()) // 1,2,3 console.log([1, 2, 3].sx_join( '*' )) // 1*2*3 |
12、flat
1 2 3 4 5 6 7 8 9 10 11 12 | Array.prototype.sx_flat = function () { let arr = this while (arr.some(item => Array.isArray(item))) { arr = [].concat(...arr) } return arr } const testArr = [1, [2, 3, [4, 5]], [8, 9]] console.log(testArr.sx_flat()) // [1, 2, 3, 4, 5, 8, 9] |
Object篇
定义一个测试对象
1 2 3 4 5 | const obj = { name: '林三心' , age: 22, gender: '男' } |
13、entries
用处:将对象转成键值对数组
1 2 3 4 5 6 7 8 9 10 | Object.prototype.sx_entries = function (obj) { const res = [] for ( let key in obj) { obj.hasOwnProperty(key) && res.push([key, obj[key]]) } return res } console.log(Object.sx_entries(obj)) // [ [ 'name', '林三心' ], [ 'age', 22 ], [ 'gender', '男' ] ] |
14、fromEntries
用处:跟entries
相反,将键值对数组转成对象
1 2 3 4 5 6 7 8 9 10 11 | Object.prototype.sx_fromEntries = function (arr) { const obj = {} for ( let i = 0; i < arr.length; i++) { const [key, value] = arr[i] obj[key] = value } return obj } console.log(Object.sx_fromEntries([[ 'name' , '林三心' ], [ 'age' , 22], [ 'gender' , '男' ]])) // { name: '林三心', age: 22, gender: '男' } |
15、keys
用处:将对象的key转成一个数组合集
1 2 3 4 5 6 7 8 9 10 | Object.prototype.sx_keys = function (obj) { const keys = [] for ( let key in obj) { obj.hasOwnProperty(key) && res.push(key) } return keys } console.log(Object.keys(obj)) // [ 'name', 'age', 'gender' ] |
16、values
用处:将对象的所有值转成数组合集
1 2 3 4 5 6 7 8 9 10 | Object.prototype.sx_values = function (obj) { const values = [] for ( let key in obj) { obj.hasOwnProperty(key) && values.push(obj[key]) } return values } console.log(Object.sx_values(obj)) // [ '林三心', 22, '男' ] |
17、instanceOf
用处:A instanceOf B,判断A是否经过B的原型链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function instanceOf(father, child) { const fp = father.prototype var cp = child.__proto__ while (cp) { if (cp === fp) { return true } cp = cp.__proto__ } return false } function Person(name) { this .name = name } const sx = new Person( '林三心' ) console.log(instanceOf(Person, sx)) // true console.log(instanceOf(Person, sx2)) // false |
18、is
用处:Object.is(a, b),判断a是否等于b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Object.prototype.sx_is = function (x, y) { if (x === y) { // 防止 -0 和 +0 return x !== 0 || 1 / x === 1 / y } // 防止NaN return x !== x && y !== y } const a = { name: '林三心' } const b = a const c = { name: '林三心' } console.log(Object.sx_is(a, b)) // true console.log(Object.sx_is(a, c)) // false |
Function篇
19、call
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Function.prototype.sx_call = function (obj, ...args) { obj = obj || window // Symbol是唯一的,防止重名key const fn = Symbol() obj[fn] = this // 执行,返回执行值 return obj[fn](...args) } const testobj = { name: '林三心' , testFn(age) { console.log(`${ this .name}${age}岁了`) } } const testobj2 = { name: 'sunshine_lin' } testobj.testFn.sx_call(testobj2, 22) // sunshine_lin22岁了 |
20、apply
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Function.prototype.sx_apply = function (obj, args) { obj = obj || window // Symbol是唯一的,防止重名key const fn = Symbol() obj[fn] = this // 执行,返回执行值 return obj[fn](...args) } const testobj = { name: '林三心' , testFn(age) { console.log(`${ this .name}${age}岁了`) } } const testobj2 = { name: 'sunshine_lin' } testobj.testFn.sx_apply(testobj2, [22]) // sunshine_lin22岁了 |
String篇
21、slice
参数代表含义
- start:开始截取的字符索引(包含此字符)
- end:结束截取的字符索引(不包含此字符)
注意点
- start > end:返回空字符串
- start < 0:
start = 数组长度 + start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | String.prototype.sx_slice = function (start = 0, end) { start = start < 0 ? this .length + start : start end = !end && end !== 0 ? this .length : end if (start >= end) return '' let str = '' for ( let i = start; i < end; i++) { str += this [i] } return str } console.log(str.sx_slice(2)) // nshine_lin console.log(str.sx_slice(-2)) // in console.log(str.sx_slice(-9, 10)) // shine_l console.log(str.sx_slice(5, 1)) // '' |
22、substr
参数代表含义
- start:开始截取的字符索引(包含此字符)
- length:截取的长度
注意点
- start < 0:
start = 数组长度 + start
- length超出所能截取范围,需要做处理
- length < 0:返回空字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | String.prototype.sx_substr = function (start = 0, length) { if (length < 0) return '' start = start < 0 ? this .length + start : start length = (!length && length !== 0) || length > this .length - start ? this .length : start + length let str = '' for ( let i = start; i < length; i++) { str += this [i] } return str } console.log(str.sx_substr(3)) // shine_lin console.log(str.sx_substr(3, 3)) // shi console.log(str.sx_substr(5, 300)) // ine_lin |
23、substring
功能与slice
大致相同
区别之处
- start > end:互换值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | String.prototype.sx_sunstring = function (start = 0, end) { start = start < 0 ? this .length + start : start end = !end && end !== 0 ? this .length : end if (start >= end) [start, end] = [end, start] let str = '' for ( let i = start; i < end; i++) { str += this [i] } return str } console.log(str.sx_sunstring(2)) // nshine_lin console.log(str.sx_sunstring(-2)) // in console.log(str.sx_sunstring(-9, 10)) // shine_l console.log(str.sx_sunstring(5, 1)) // unsh |
Promise篇
24、all
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 如果所有Promise都成功,则返回成功结果数组
- 如果有一个Promise失败,则返回这个失败结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function all(promises) { const result = [] let count = 0 return new MyPromise((resolve, reject) => { const addData = (index, value) => { result[index] = value count++ if (count === promises.length) resolve(result) } promises.forEach((promise, index) => { if (promise instanceof MyPromise) { promise.then(res => { addData(index, res) }, err => reject(err)) } else { addData(index, promise) } }) }) } |
25、race
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 哪个Promise最快得到结果,就返回那个结果,无论成功失败
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function race(promises) { return new MyPromise((resolve, reject) => { promises.forEach(promise => { if (promise instanceof MyPromise) { promise.then(res => { resolve(res) }, err => { reject(err) }) } else { resolve(promise) } }) }) } |
26、allSettled
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 把每一个Promise的结果,集合成数组,返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | function allSettled(promises) { return new Promise((resolve, reject) => { const res = [] let count = 0 const addData = (status, value, i) => { res[i] = { status, value } count++ if (count === promises.length) { resolve(res) } } promises.forEach((promise, i) => { if (promise instanceof MyPromise) { promise.then(res => { addData( 'fulfilled' , res, i) }, err => { addData( 'rejected' , err, i) }) } else { addData( 'fulfilled' , promise, i) } }) }) } |
27、any
any与all相反
- 接收一个Promise数组,数组中如有非Promise项,则此项当做成功
- 如果有一个Promise成功,则返回这个成功结果
- 如果所有Promise都失败,则报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function any(promises) { return new Promise((resolve, reject) => { let count = 0 promises.forEach((promise) => { promise.then(val => { resolve(val) }, err => { count++ if (count === promises.length) { reject( new AggregateError( 'All promises were rejected' )) } }) }) }) } } |
困难篇
28、Array.prototype.splice
难点
- 截取长度和替换长度的比较,不同情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Array.prototype.sx_splice = function (start, length, ...values) { length = start + length > this .length - 1 ? this .length - start : length const res = [], tempArr = [... this ] for ( let i = start; i < start + values.length; i++) { this [i] = values[i - start] } if (values.length < length) { const cha = length - values.length for ( let i = start + values.length; i < tempArr.length; i++) { this [i] = tempArr[i + cha] } this .length = this .length - cha } if (values.length > length) { for ( let i = start + length; i < tempArr.length; i++) { this .push(tempArr[i]) } } for ( let i = start; i < start + length; i++) { res.push(tempArr[i]) } return res } |
29、Object.assign
难点
- assign接收多个对象,并将多个对象合成一个对象
- 这些对象如果有重名属性,以后来的对象属性值为准
- assign返回一个对象,
这个对象 === 第一个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Object.prototype.sx_assign = function (target, ...args) { if (target === null || target === undefined) { throw new TypeError( 'Cannot convert undefined or null to object' ) } target = Object(target) for ( let nextObj of args) { for ( let key in nextObj) { nextObj.hasOwnProperty(key) && (target[key] = nextObj[key]) } } return target } const testa = { name: '林三心' } const testb = { name: 'sunshine_lin' , age: 22 } const testc = { age: 18, gender: '男' } const testd = Object.sx_assign(testa, testb, testc) console.log(testd) // { name: 'sunshine_lin', age: 18, gender: '男' } console.log(testa === testd) // true |
30、Function.prototype.bind
难点:
- bind是返回一个函数,而不是执行结果
- bind返回的函数,拿来当做构造函数,该怎么处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Function.prototype.sx_bind = function (obj, ...args) { obj = obj || window // Symbol是唯一的,防止重名key const fn = Symbol() obj[fn] = this const _this = this const res = function (...innerArgs) { console.log( this , _this) if ( this instanceof _this) { this [fn] = _this this [fn](...[...args, ...innerArgs]) delete this [fn] } else { obj[fn](...[...args, ...innerArgs]) delete obj[fn] } } res.prototype = Object.create( this .prototype) return res } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗