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

网站虚拟主持人制作泰安企业建站公司电话

网站虚拟主持人制作,泰安企业建站公司电话,佛山网站建设维护,大兴安岭建设局网站前言 #x1f4eb; 大家好#xff0c;我是南木元元#xff0c;热爱技术和分享#xff0c;欢迎大家交流#xff0c;一起学习进步#xff01; #x1f345; 个人主页#xff1a;南木元元 今天接着上篇再来分享一下10个常见的JavaScript手写功能。 目录 1.实现继承 ES5继…前言 大家好我是南木元元热爱技术和分享欢迎大家交流一起学习进步   个人主页南木元元 今天接着上篇再来分享一下10个常见的JavaScript手写功能。 目录 1.实现继承 ES5继承寄生组合式继承 ES6继承 2.获取URL参数 split方法 URLSearchParams方法 3.手写reduce 4.实现观察者模式 5.实现发布-订阅模式 6.异步控制并发数 7.实现Promise.all 8.使用setTimeout实现setInterval 9.实现每隔一秒打印 1,2,3,4 10.循环打印红黄绿 结语 1.实现继承 ES5继承寄生组合式继承 寄生组合式继承是对组合式继承调用了2次父构造方法的改进使用父类的原型的副本来作为子类的原型这样就只调用一次父构造函数避免了创建不必要的属性。 function Parent (name) {this.name name;this.colors [red, blue, green]; } Parent.prototype.getName function () {console.log(this.name) } function Child (name, age) {Parent.call(this, name);//借用构造函数的方式来实现属性的继承和传参this.age age; }//这里不用Child.prototype new Parent()原型链方式的原因是会调用2次父类的构造方法导致子类的原型上多了不需要的父类属性 Child.prototype Object.create(Parent.prototype);//这里就是对组合继承的改进,创建了父类原型的副本 Child.prototype.constructor Child;//把子类的构造指向子类本身var child1 new Child(kevin, 18); console.log(child1.colors);//[ red, blue, green ] child1.getName();//kevin 测试结果 ES6继承 在ES6中可以使用class类去实现继承。使用extends表明继承自哪个父类并且在子类构造函数中必须调用super。 class Parent {constructor(name) {this.name name;}getName() {console.log(this.name);} }class Child extends Parent {constructor(name, age) {//使用this之前必须先调用super(),它调用父类的构造函数并绑定父类的属性和方法super(name);//之后子类的构造函数再进一步访问和修改 thisthis.age age;} }// 测试 let child new Child(kevin, 18); console.log(child.name); // kevin console.log(child.age); // 18 child.getName(); // kevin 测试结果 es5继承和es6继承的区别 ES5继承是先创建子类的实例对象然后再将父类方法添加到thisParent.call(this)上。ES6的继承不同实质是先将父类实例对象的属性和方法加到this上面所以必须先调用super方法然后再用子类的构造函数修改this。 2.获取URL参数 split方法 function getParams(url) {const res {}//判断字符串中是否可以找到?if (url.includes(?)) {const str url.split(?)[1]const arr str.split()arr.forEach(item {const key item.split()[0]const val item.split()[1]res[key] decodeURIComponent(val) // 中文需解码})}return res }// 测试 const user getParams(http://www.baidu.com?user%E9%98%BF%E9%A3%9Eage16) console.log(user) // { user: 阿飞, age: 16 } 测试结果 URLSearchParams方法 URLSearchParams方法返回一个 URLSearchParams 对象来处理 URL 的查询字符串。 // 该url的url.search为?foo1bar2 let url new URL(https://example.com?foo1bar2); // 创建一个URLSearchParams实例即URLSearchParams { foo 1, bar 2 } let searchParams new URLSearchParams(url.search); // 键值对列表URLSearchParams Iterator { [ foo, 1 ], [ bar, 2 ] } console.log(searchParams.entries()); // 将键值对列表转换为一个对象 let res Object.fromEntries(searchParams.entries()); console.log(res); //{ foo: 1, bar: 2 } 测试结果 3.手写reduce reduce的使用 //普通数组求和 let arr [1,2,3,4,5,6,7,8,9,10] arr.reduce((prev, cur) { return prev cur }, 0)//55 //多维数组求和 let arr [1,2,3,[[4,5],6],7,8,9] arr.flat(Infinity).reduce((prev, cur) { return prev cur }, 0)//45 //对象数组求和 let arr [{a:9, b:3, c:4}, {a:1, b:3}, {a:3}] arr.reduce((prev, cur) {return prev cur[a];//13 求对象数组中所有属性为a的和 }, 0) reduce的实现 Array.prototype.myReduce function (cb, initialValue) {const arr this; //this就是调用reduce方法的数组let total initialValue ? initialValue : arr[0]; //不传默认取数组第一项let startIndex initialValue ? 0 : 1; // 有初始值的话从0遍历否则从1遍历for (let i startIndex; i arr.length; i) {total cb(total, arr[i], i, arr); //参数为初始值、当前值、索引、当前数组}return total; };//测试 let arr [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let res arr.myReduce((total, cur) {return total cur; }, 0); console.log(res);//55 测试结果 4.实现观察者模式 观察者模式定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都将得到通知。 // 被观察者 学生 class Subject {constructor() {this.state happy;this.observers []; // 存储所有的观察者}//新增观察者add(o) {this.observers.push(o);}//获取状态getState() {return this.state;}// 更新状态并通知setState(newState) {this.state newState;this.notify();}//通知所有的观察者notify() {this.observers.forEach((o) o.update(this));} }// 观察者 父母和老师 class Observer {constructor(name) {this.name name;}//更新update(student) {console.log(亲爱的${this.name} 通知您当前学生的状态是${student.getState()});} }let student new Subject(); let parent new Observer(父母); let teacher new Observer(老师); //添加观察者 student.add(parent); student.add(teacher); //设置被观察者的状态 student.setState(sad);测试结果 详细可以去看我的这篇文章——JavaScript 简单实现观察者模式和发布-订阅模式 5.实现发布-订阅模式 发布订阅模式跟观察者模式很像但它的发布和订阅是不互相依赖的因为有一个统一调度中心。 class EventBus {constructor() {// 缓存列表用来存放注册的事件与回调this.cache {};}// 订阅事件on(name, cb) {// 如果当前事件没有订阅过就给事件创建一个队列if (!this.cache[name]) {this.cache[name] []; //由于一个事件可能注册多个回调函数所以使用数组来存储事件队列}this.cache[name].push(cb); }// 触发事件emit(name, ...args) {// 检查目标事件是否有监听函数队列if (this.cache[name]) {// 逐个调用队列里的回调函数this.cache[name].forEach((callback) {callback(...args);});}}// 取消订阅off(name, cb) {const callbacks this.cache[name]; const index callbacks.indexOf(cb); if (index ! -1) {callbacks.splice(index, 1); }}// 只订阅一次once(name, cb) {// 执行完第一次回调函数后自动删除当前订阅事件const fn (...args) {cb(...args); this.off(name, fn); };this.on(name, fn);} }// 测试 let eventBus new EventBus(); let event1 function (...args) {console.log(通知1-订阅者小陈老师,小明同学当前心情状态${args}) }; // 订阅事件只订阅一次 eventBus.once(teacherName1, event1); // 发布事件 eventBus.emit(teacherName1, 教室, 上课, 打架, 愤怒); eventBus.emit(teacherName1, 教室, 上课, 打架, 愤怒); eventBus.emit(teacherName1, 教室, 上课, 打架, 愤怒);测试结果 6.异步控制并发数 场景实现一个带并发限制的异度调度器保证同时运行的任务最多有两个。 class Controll {constructor(limit) {// 待执行的任务队列this.waitTasks []; // 正在执行的任务队列this.runTasks []; // 允许同时运行的任务数量this.limit limit; }//添加任务add(task) {//当前执行任务队列小于并发限制就执行该任务if (this.runTasks.length this.limit) {this.run(task);} else {//将该任务添加到等待队列this.waitTasks.push(task);}}//执行任务run(task) {//push添加元素并返回新的数组长度const len this.runTasks.push(task);const index len - 1;task().then(() {//执行完后删除任务this.runTasks.splice(index, 1);if (this.waitTasks.length 0) {//执行并删除等待队列中的第一个任务this.run(this.waitTasks.shift());}});} }//测试允许同时执行2个任务 const scheduler new Controll(2); //添加任务 const addTask (time, order) {scheduler.add(async () {//定时器打印await new Promise((resolve) {setTimeout(resolve, time);//定时器时间到了就resolve执行成功然后打印结果});console.log(order);}); }; //添加任务参数为定时器时间和打印数字 addTask(1000, 1); addTask(500, 2); addTask(300, 3); addTask(400, 4); 测试结果 7.实现Promise.all function all(promises) {return new Promise(function(resolve, reject) {//传入参数为一个空的可迭代对象直接resolveif (promises.length 0) {resolve([]);} else {const res [];let count 0;for (let i 0; i promises.length; i) {//为什么不直接promise[i].then, 因为promise[i]可能不是一个promise, 也可能是普通值Promise.resolve(promises[i]).then((data) {res[i] data;count;if (count promises.length) {resolve(res);//如果所有Promise都成功则返回成功结果数组}}).catch((err) {reject(err);//如果有一个Promise失败则返回这个失败结果});}}}) }// 测试 const promise1 Promise.resolve(3); const promise2 42; const promise3 new Promise((resolve, reject) {setTimeout(resolve, 100, foo); });all([promise1, promise2, promise3]).then((values) {console.log(values); //[3, 42, foo] }); 测试结果 8.使用setTimeout实现setInterval setInterval的缺点setInterval 的作用是每隔一段时间执行一个函数但是这个执行不是真的到了时间立即执行它真正的作用是每隔一段时间将事件加入事件队列中去只有当当前的执行栈为空的时候才能去从事件队列中取出事件执行。所以可能会出现这样的情况就是当前执行栈执行的时间很长导致事件队列里边积累多个定时器加入的事件当执行栈结束的时候这些事件会依次执行因此就不能到间隔一段时间执行的效果。 针对 setInterval 的这个缺点我们可以使用 setTimeout 递归调用来模拟 setInterval这样我们就确保了只有一个事件结束了我们才会触发下一个定时器事件这样解决了 setInterval 的问题。 实现思路是使用递归函数不断地去执行setTimeout从而达到setInterval的效果。 function mySetInterval(fn, timeout) {// 控制器控制定时器是否继续执行var timer {flag: true,};// 设置递归函数模拟定时器执行function interval() {if (timer.flag) {fn();setTimeout(interval, timeout);//递归}}// 启动定时器setTimeout(interval, timeout);// 返回控制器return timer; }let timer mySetInterval(() {console.log(1); }, 1000); //3秒后停止定时器 setTimeout(() (timer.flag false), 3000); 测试结果 9.实现每隔一秒打印 1,2,3,4 // 1.使用 let 块级作用域 for (let i 0; i 5; i) {setTimeout(() {console.log(i);}, i * 1000); }// 2.使用闭包实现 for (var i 0; i 5; i) {(function(j) {setTimeout(() {console.log(j);}, j * 1000);})(i); } 测试结果 10.循环打印红黄绿 场景红灯 3s 亮一次绿灯 1s 亮一次黄灯 2s 亮一次如何让三个灯不断交替重复亮灯 三个亮灯函数 function red() {console.log(red); } function green() {console.log(green); } function yellow() {console.log(yellow); } 用async/await实现 const task (timer, light) {return new Promise((resolve, reject) {setTimeout(() {if (light red) {red();} else if (light green) {green();} else if (light yellow) {yellow();}resolve();//注意要resolve让Promise状态变成fulfilled不然会一直是pending无法往下执行}, timer);}); }; const taskRunner async () {await task(3000, red);await task(2000, green);await task(1000, yellow);taskRunner(); //递归 }; taskRunner(); 测试结果 结语 本文总结了前端常见的一些手写功能你是不是全都掌握了呢欢迎在评论区交流。 如果此文对你有帮助的话欢迎关注、点赞、⭐收藏、✍️评论支持一下博主~
http://www.w-s-a.com/news/170795/

相关文章:

  • 苏州高端网站建设kgwl互动网站建设的主页
  • 宿州网站建设哪家公司好个人网站制作方法
  • 网站正能量晚上在线观看视频站长之家关键词挖掘工具
  • 建设网站怎么判断是电脑还是手机仿租号网站源码网站开发
  • seo百度网站排名软件重庆巫山网站设计公司
  • 搭建视频播放网站网站排名诊断
  • 网站域名注册网站centos做网站服务器
  • 网站服务器共享的 vpsh5页面制作软件电脑版
  • 免费手机网站申请上海网站建设设计公司哪家好
  • 站长工具大全企业网上书店网站建设设计
  • 做网站的专业公司公司网站是做的谷歌的
  • 做网站前期工作wordpress图片并排
  • 免费注册网站哪个好wordpress评论修改
  • 合肥模板网站建设软件赤峰公司网站建设
  • 毕业设计都是做网站吗深圳网站制作企业邮箱
  • 网站排名 优帮云小规模公司简介怎么写
  • 那个做头像的网站好选择手机网站建设
  • 设计一个网站花多少时间做视频网站适合用什么服务器
  • asp网站开发环境订单系统单页面网站怎么做
  • 山东网站建设都有那些企业推广策略
  • 网站开发文档是什么概念衣服销售网站建设规划书范文
  • 中国建筑装饰网官网企业网站设计优化公司
  • 南海建设工程交易中心网站c2c交易平台有哪些?
  • 有没有专业做网站架构图的软件番禺建设网站哪个好
  • 建立网站第一步整站seo优化公司
  • php网站开发文章管理系统wordpress 评论 顶踩 心 插件
  • 网站做百度收录的意义html网页设计代码作业代码
  • 网站推广怎么做 知乎衡水做网站开发的
  • 重庆忠县网站建设报价网页构建
  • 怎么自己做单页网站怎么在阿里做网站