- Array.prototype.fill2 = function (value, start, end) {
- const length = this.length; // 获取数组的长度
-
- start = start >> 0; // 将start转换为整数
- // 如果end参数未填写,则默认为数组的长度,否则将end转换为整数
- end = typeof end === 'undefined' ? length : end >> 0;
- // 将start限制在合法范围内,最小值为0,最大值为数组的长度
- start = start >= 0 ? Math.min(start, length) : Math.max(start + length, 0);
- // 将end限制在合法范围内,最小值为0,最大值为数组的长度
- end = end >= 0 ? Math.min(end, length) : Math.max(end + length, 0);
- // 使用指定的value填充从start到end范围内的数组索引
- while (start < end) {
- this[start] = value;
- start++;
- }
- // 返回被修改后的数组
- return this;
- }
这段代码实现了一个自定义的fill2方法,用于在数组中指定的范围内填充指定的值。它接受三个参数:value表示要填充的值,start表示填充的起始索引,end表示填充的结束索引(不包含在内)。
在代码中,首先获取了数组的长度。然后对start和end参数进行处理,将它们转换为整数,并进行范围限制,确保它们在合法的范围内。接下来,使用一个循环从start索引开始,逐个将数组的元素设置为指定的value值,直到达到end索引为止。最后,返回被修改后的数组。
通过使用这个自定义的fill2方法,我们可以在数组中指定的范围内快速填充指定的值。
- Array.prototype.myMap = function (callbackFn, thisArg) {
- if (this == "undefined" || this == "null") {
- throw new TypeError("can not read property 'map' of undefined or null");
- }
- if (typeof callbackFn !== "function") {
- throw `${callbackFn} is not a function`;
- }
- let O = Object(this); // 将当前数组对象转换为对象类型
- let T = thisArg; // 设置回调函数的this值
- let len = O.length >>> 0; // 获取数组的长度
- let A = new Array(len); // 创建一个新的数组,用于存储映射后的值
- for (let k = 0; k < len; k++) {
- for (k in O) {
- let KValue = O[k]; // 获取当前索引的值
- let mapValue = callbackFn.call(T, KValue, k, O); // 调用回调函数进行映射操作
- A[k] = mapValue; // 将映射后的值存储到新数组中
- }
- }
- return A; // 返回映射后的新数组
- }
-
- let arr = [1, 2, 3, 4];
- let arr2 = arr.myMap(function (currentValue, index, Array) {
- console.log(currentValue, index, Array);
- return currentValue + 1;
- });
- console.log(arr2);
- Array.prototype.myMap = function (callbackFn, thisArg) {
- if (this == "undefined" || this == "null") {
- throw new TypeError("can not read property 'map' of undefined or null")
- }
- if (typeof callbackFn !== "function") {
- throw `${callbackFn} is not a function`
- }
- let length = Object(this).length >>> 0
- let newArrray = []
- let i = 0
- while (i < length) {
- if (i in this) {
- //2. call修改了函数callbackFn的this指向,指向thisArg,后面的this还是指向的 arr,作为参数传给函数
- newArrray.push(callbackFn.call(thisArg, this[i],i,this))
- }
- i++
- }
- return newArrray
- }
-
- let arr = [1,2,3,4]
- // 1.绑定实例:用类实例对象去调用成员方法,此时this的指向为调用的实例对象 arr
- let arr2 = arr.myMap(function(currentValue,index,Array){
- // 3.此时的参数 currentValue,index,Array 对应2.传入的参数:this[i],i,this
- // 此时this为callbackFn的指向 this.Args 也就是 {message:"🐟"}
- console.log(currentValue,index,Array,this);
- return ++currentValue
- },{message:"🐟"})
- console.log(arr2);
- function myThrottle(myFn,myDelay){
- let initState = true
- return function(...args){
- if(!initState) return
- initState = false
- setTimeout(() => {
- myFn.apply(this,args)
- initState = true
- }, myDelay);
- }
- }
-
- function mytest(arguments){
- console.log('test'+ arguments); //testppp
- }
- const oneTest = myThrottle(mytest,500)
- oneTest('ppp')
- function debounce(fn,delay){
- var initWaitTime = null
- return function(...args){
- clearTimeout(initWaitTime)
- initWaitTime = setTimeout(() => {
- fn.apply(this,args)
- },delay)
- }
- }
-
- function testDebounce(){
- console.log('防抖');
- }
- const test4 = debounce(testDebounce,1000)
- console.log(test4);
- test4()
- test4()
- test4()
- class Scheduler {
- constructor(max) {
- this.max = max
- this.count = 0
- this.queue = []
- }
- add(p) {
- this.queue.push(p)
- this.start()
- }
- start() {
- if (this.count >= this.max || !this.queue.length) return
- this.count++
- this.queue.shift()().finally(() => {
- this.count--
- this.start()
- })
- }
- }
-
- // 延迟函数
- const sleep = time => new Promise(resolve => setTimeout(resolve, time));
-
- // 同时进行的任务最多2个
- const scheduler = new Scheduler(2);
-
- // 添加异步任务
- // time: 任务执行的时间
- // val: 参数
- const addTask = (time, val) => {
- scheduler.add(() => {
- return sleep(time).then(() => console.log(val));
- });
- };
-
- addTask(1000, '1');
- addTask(500, '2');
- addTask(300, '3');
- addTask(400, '4');
- // 2
- // 3
- // 1
- // 4
- class Scheduler {
- constructor(maxNum) {
- this.maxNum = maxNum; // 最大同时执行任务的数量
- this.count = 0; // 当前正在执行的任务数量
- this.taskList = []; // 任务列表,用于存储待执行的任务
- }
-
- addTask(time, val) {
- this.taskList.push([time, val]); // 将任务添加到任务列表中
- }
-
- start() {
- if (!this.taskList.length) return; // 如果任务列表为空,则直接返回
- if (this.count < this.maxNum) { // 如果当前正在执行的任务数量小于最大值
- const [time, val] = this.taskList.shift(); // 从任务列表中取出一个任务
- this.count++; // 增加正在执行的任务数量
- setTimeout(() => { // 使用setTimeout延迟执行任务
- console.log(val); // 打印任务的值
- this.count--; // 减少正在执行的任务数量
- this.start(); // 继续执行下一个任务
- }, time * 1000); // 将时间转换为毫秒,并设置延迟执行的时间
- this.start(); // 继续执行下一个任务
- }
- }
- }
深拷贝函数:
- function deepClone(target, hashMap = new WeakMap()) {
-
-
- // 基本数据类型,直接返回
- if (typeof target !== "object" || target == null) {
- /*
- 函数,则调用函数并返回结果(虽然这里是同一个存储空间
- 但是如果修改函数时,相当于重写函数,会自动分配堆内存存放新函数,也就是不会改变原函数)
- */
- if (target instanceof Function) return target.call(this, ...arguments);
- return target;
- }
-
- // 日期对象,则创建一个新的日期对象并返回
- if (target instanceof Date) return new Date(target);
-
- // 正则表达式对象,则创建一个新的正则表达式对象并返回
- if (target instanceof RegExp) return new RegExp(target);
-
- // 创建一个与目标对象构造函数相同的新对象
- let res = new target.constructor();
-
- // 如果哈希表中已经存在目标对象,则直接返回对应的新对象
- if (hashMap.get(target)) return hashMap.get(target);
-
- // 将新对象和目标对象存入哈希表中
- hashMap.set(res, target);
-
- // 遍历目标对象的属性
- for (let key in target) {
- // 递归调用深拷贝函数,复制目标对象的属性值,并赋值给新对象的对应属性
- res[key] = deepClone(deepClone(target[key], hashMap));
- }
-
- // 返回新对象
- return res;
- }