![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
前端
文章平均质量分 80
懒人Ethan
毕业于天津理工大学,拥有超过10年dotnet和前端开发经验。PMP认证,Microsoft Certified认证。精通ASP.NET/ASP.NET Core、Angular和Vue的开发。
展开
-
JavaScript中的Lexical Environment
本文主要介绍JavaScript中的一个重要概念Lexical Environment,它可以帮助我们解释我们为什么可以通过嵌套方法,共享数据,以及为什么可以在函数中定义一个和全局变量同名的变量,并且不会影响到全局变量。原创 2024-03-22 14:13:18 · 692 阅读 · 0 评论 -
JavaScript中的Hoisting
下面的代码并不会报错,可以正常执行。var a = 0;代码最后执行结果是打印undefined。我们讨论一下代码背后的原因。首先, 创建JS Engine会创建GEC;然后, 代码在GEC中执行。此时,a的值就是undefined,所以打印出来的也是undefined。我们打开浏览器通过断点执行,可以看到同样的执行结果。因为a变量在最高的代码层级上,通过var被定义,所以在创建GEC的时候,会先将它赋值为undefined,后面根据代码的执行,再进行其它赋值。原创 2024-03-14 15:46:09 · 360 阅读 · 0 评论 -
Javascript的Execution Context
本文主要通过一个实例,来理解什么是Javascript中的Execution Context,以及在JavaScript执行过程中,Execution Context是如何工作的。原创 2024-03-14 14:33:59 · 1045 阅读 · 1 评论 -
基于原生Javascript的放大镜插件的设计和实现
本文主要介绍一个前端放大镜插件的设计和实现,该插件可以将图片的指定区域进行局部放大,插件运行不依赖任何第三方库,可以在Chrome或Edge的常见版本上运行。原创 2023-03-24 17:00:08 · 835 阅读 · 1 评论 -
基于原生Javascript的Carousel设计及实现
本文主要介绍一个无缝轮播图的基本设计原理和实现方式,该轮播图不依赖任何第三方插件或组件库,可以在常用的Chrome或Edge浏览器上正常运行。原创 2023-03-24 11:01:25 · 696 阅读 · 1 评论 -
JS中数组和树型数据的相互转化
在前后端分离的开发工作中,我们经常从后端的WebAPI中获取到1维数据,前端需要将这些数据转换为树型结构。例如多级菜单数据,我们需要通过id和pid等栏位,将1维数组数据转换成一个树型结构,然后再进行页面渲染。本文主要介绍两个JS方法,方便我们将数组转换成树,或将树形结构转换成1维数组。原创 2022-10-31 15:55:30 · 997 阅读 · 0 评论 -
draggable 和 sortable的JS原生实现
本文主要利用html 5的draggable原生特性,实现一个可拖拽的效果。我们可以创建包含多个页面节点的容器,每个容器可以包含多个节点。通过拖拽,可以移动一个容器内的节点到其他容器,每个容器内的节点和以通过拖拽改变排列顺序。原创 2022-10-24 09:13:10 · 1289 阅读 · 0 评论 -
介绍一种在Vue 3.0 下封装第三方插件的方法
Vue在升级到3.0之后,我们不能再按照2.0的方式,在其原型链上封装第三方的插件对象。本文仿照Vuex的使用方法,结合Vue3.0的Composition API,实现一种在Vue 3.0下封装第三方插件的方法。原创 2022-08-28 12:06:45 · 1109 阅读 · 0 评论 -
Javascript中的replace方法与正则表达式的结合使用
概要在前端开发过程中,字符串的replace方法在数据处理中非常常用。本文通过一个关键字高亮显示的实例和一个文字插值的实例,来说明replace方法如何结合正则表达式,从而更加灵活的满足各种需求。replace方法基本介绍函数参数和返回值regexp (pattern)一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。substr (pattern)一个将被 newSubStr 替换的 字符串。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替原创 2022-04-14 22:46:17 · 2450 阅读 · 0 评论 -
Vue的指令中如何传递更多参数
概要我们在使用Vue的开发项目中,经常用自定义指令(directive)来封装一系列的DOM操作,这样做非常方便。一般来说,指令是使用动态指令参数来获取App中的数据。但是有些时候,自定义指令需要更多的数据来完成更复杂的功能,例如在指令中调用当前App实例的nextTick方法,以确保所有DOM元素加载完成,再进行DOM操作。还有一些情况,我们需要将一些全局配置参数传递给指令,已有的参数专递方式,显然无法满足这些需求。本文介绍一种扩展指令参数的方法,使其可以接收更多参数。该方法在Vue 2.0和 Vu原创 2022-03-25 22:57:40 · 5793 阅读 · 0 评论 -
JavaScript中的instanceof运算符
JavaScript中的原型,原型链和instanceof运算符详解。原创 2022-03-17 15:39:17 · 6071 阅读 · 0 评论 -
Javascript数组常用方法重写之flat
概要本文主要目的是探讨在ES5中,数组原型链上flat方法是如何实现的。文章提供了基于reduce方法和基于map方法的两种实现思路。map和reduce方法的底层实现,请参看我的博文Javascript数组常用方法重写之map,reduce,some,every代码实现基本功能:将多维数组转换为1维数组。基于ES5 和 reduce方法的实现function flaten(temp){ arr = this; temp = temp || []; return arr.原创 2022-01-03 15:35:39 · 627 阅读 · 0 评论 -
Javascript数组常用方法重写之map,reduce,some,every
概要我们在前端开发过程中,经常使用到各种数组的原生方法。为了更好的理解和使用这些原生方法,所以笔者试着重写了这些方法,并实现了相同的功能。本文主要对map,reduce,some,every这四个原型方法进行重写。代码实现由于新方法也要定义在原型链上,为了避免重复,所以本文参考C#的LINQ方法命名。具体如下:原型方法名称重写后的方法名称mapSelectreduceAggregate/AggregateLINQsomeAnyeveryAllma原创 2021-12-27 16:44:30 · 1826 阅读 · 0 评论 -
Javascript数组常用方法重写之find,findIndex,filter,forEach
概要我们在前端开发过程中,经常使用到各种数组的原生方法。为了更好的理解和使用这些原生方法,所以笔者试着重写了这些方法,并实现了相同的功能。本文主要对find,findIndex,filter,forEach这四个原型方法进行重写。代码实现由于新方法也要定义在原型链上,为了避免重复,所以本文参考C#的LINQ方法命名。具体如下:原型方法名称重写后的方法名称findFirstfindIndexfirstIndexfilterWhereforEachEach原创 2021-12-24 16:44:45 · 1261 阅读 · 0 评论 -
Javascript 深度克隆中的循环引用问题解决和代码优化
概要在前端项目开发中,我们经常需要深度克隆JS对象。在克隆代码开发过程中,我们经常会遇到数组判定方法的问题,对象循环引用的问题。本文通过实例来解决上述问题代码及实现常见深度克隆JS对象的代码function deepClone(origin){ if (origin == undefined || typeof origin !== "object"){ return origin; } if (origin instanceof Date){原创 2021-12-21 17:31:37 · 2415 阅读 · 0 评论 -
Javascrip中的undefined和null作为函数实参的问题
概要今天在前端JS代码开发过程中遇到一个函数传值的问题,和大家分享一下。问题提出业务逻辑代码已经略去,关键代码如下:var obj = {a:1};function test(obj){ obj = 2;}test(obj["b"]);console.log(obj);代码执行结果并不是如我们所想,obj.b 并不存在,结果如下:我们提前将obj.b 赋值为nullvar obj = {a:1};obj.b = null;function test(obj){原创 2021-12-21 12:19:41 · 349 阅读 · 0 评论 -
Typescript中的as const断言
概要typescript在开发过程中广泛被应用,typescript的断言特性更是重中之重,今天和大家来讨论一下as const断言。代码和讨论我们首先来看一段代码, 如下:let a:string = "aaa";const b = "aaa";以上代码除了const和let两个关键子本身的不同之外,就是a和b两个变量的实际类型是不同的。变量a实际为一种宽泛的字符串类型,只要是字符串,即可赋值给变量a变量b实际为一种具体的值类型,类型为“aaa”,不可被修改,因为其他任何字符串赋值给b原创 2021-10-24 23:41:17 · 6727 阅读 · 2 评论 -
Javascript中字符串去重的方法总结
概要在现实应用中,我们常常需要从页面抓取出一些数据进行二次处理。在抓取出来的数据中,常常包含大量的重复数据,需要去掉重复数据。本文介绍几种方式来去掉字符串中的重复内容。解决方案解决方案解决方案1,基于ES6的新特新, 例如Set,展开运算符等。现在要去掉字符串***aaabbbcccddd***的重复项。代码如下:var str = [... new Set("aaabbbcccddd")].join("")运行结果是: abcd该方法主要是通过将字符串转为Set,而Set这种数据结构不原创 2021-09-28 14:44:52 · 9106 阅读 · 1 评论 -
Vue 2.0源码分析之响应式数据生成的原理
概要本文通过分析Vue 2.0 源码,探讨一下在Vue 2.0的初始化过程中,如何生成响应书数据。最后我们将关键的代码抽取出来,模拟出具体的实现过程。本文使用的Vue源码版本是2.6.14。Github地址是https://github.com/vuejs/vue.git。...原创 2021-07-21 16:53:52 · 499 阅读 · 4 评论 -
为什么Vue 2.0中的this指针可以访问到data函数的返回值
概要本文通过分析Vue 2.0 源码,探讨一下为什么在Vue 2.0中,我们可以在method,filter,计算属性对应的方法中,通过this指针访问data方法的返回值。最后我们将关键的代码抽取出来,模拟出具体的实现过程。本文使用的Vue源码版本是2.6.14。Github地址是https://github.com/vuejs/vue.git。代码流程分析1. 进入初始化方法_init在/src/core/instance/index.js 中,调用_init方法function Vue (原创 2021-07-03 12:01:56 · 1326 阅读 · 0 评论 -
基于ES6的爬网脚本
爬网脚本需求介绍关键代码分析附录本文通过ES6的新特性如async函数,rest参数,正则表达式的具名组匹配等,实现了一个简单的爬网脚本。通过获取每个页面的html代码,进行正则表达式匹配,最后完成所有需求。需求介绍获取指定页面title获取指定页面顶端按钮的名称和链接地址关键代码分析我们希望通过异步请求获取每个页面html代码,再对每个页面进行分析。因此,传统的异步请求很难解决该问题,所以使用async函数,让整个异步处理和同步处理几乎没有差别,循环体中实现获取一个html代码,处理并原创 2020-08-26 16:28:31 · 131 阅读 · 0 评论 -
Vue 3.0中的v-model
Vue 3.0中的v-model指令的基本用法,相比于2.0版本,变化比较大,本文通过具体实例,帮助大家彻底搞懂。单个v-model的绑定实例中,我们定义一个BasicInput组件,组件中包含一个textbox和一个p标签。b标签同步显示输入框中的内容。BasicInput组件可以接收一个字符串作为初始值。代码如下:<template> <div> <input type="text" :value="modelValue" @input="handleIn原创 2020-10-02 18:30:49 · 4715 阅读 · 2 评论 -
基于Vue3.0 实现的无限级菜单
function deepClone(source, target) { var _tar = target || {}; let keys = Reflect.ownKeys(source); keys.map((key) => { if (typeof source[key] === "object") { _tar[key] = Object.prototype.toString.call(source[key]) === "[object Arr原创 2020-10-21 15:26:02 · 2575 阅读 · 1 评论 -
Vue 3.0中的reactive函数模拟实现
reactive函数功能reactive函数通过为当前对象生成代理对象,实现数据的响应式功能。即代理对象的任何数据改便,都可以被监控到。本文通过一个功能的模拟,来更好的理解reactive函数的功能。(function(window){ const get = () => (target,key,receiver) => { const obj = Reflect.get(target,key,receiver); console.log(`Get原创 2020-10-30 17:19:10 · 1004 阅读 · 0 评论 -
Angular中的@Self和@Host装饰器比较
概要依赖注入是Angular框架的重要组成部分。如果将root模块比作树的根节点,Angular会使用所有组件和模块的依赖注入器生成一棵注入器树,每个叶节点保存了用户定义的依赖注入的信息。默认情况下,对于依赖注入的对象,Angular会先从当前组件的注入器中开始查找,经历父组件注入器,当前模块注入器和根模块注入器。直到找到需要依赖注入的对象。@Self和@Host装饰器主要用于大型多团队的开发项目,对上述的依赖注入对象的搜索过程进行限定,避免错误引用。@Self和@Host装饰器定义上比较类似,本文原创 2020-11-30 17:15:19 · 1006 阅读 · 1 评论 -
Angular父子组件传递方法的关键点
概要Angular在父子组件传递数据时,数据既可以是我们传统意义上的数字,字符串等数值类型,也可以是一个方法。对于数值类型,只要按照文档的说明进行传递,一般不会有问题。但是对于方法的传递,则并不能与普通的数值传递划等号。本文以一个Tabs组件的错误实例来说明Angular中父子组件传递方法的注意事项。设计与实现开发需求本文通过一个Tabs组件实例来说明父子组件的方法传递,用户可以将Tabs数据和初始默认选中的Tab项作为属性传入Tabs组件。组件中每个月份为一个Tab项,每个Tab项内包含当月的销原创 2020-12-01 17:30:58 · 577 阅读 · 0 评论 -
Angular中Checkbox列表的数据双向绑定
概要Angular数据的双向绑定,要使用[(ngModel)]指令。但是,在使用过程中,我们不难发现,该指令在对CheckBox列表做双向数据绑定时候,并不是很好用。因为Angular中的[(ngModel)]无法像Vue中的v-model指令那样,接收一个数组。当前CheckBox的value值存在于数组中,则当前CheckBox处于选中状态,反之,处于未选中状态。对于CheckBox列表,一般后端传给前端的是一个选中项的Id列表,如果我们直接使用[(ngModel)]进行绑定,则需要对列表数据进行原创 2020-12-03 11:58:47 · 2318 阅读 · 0 评论 -
Bootstrap在老旧站点升级中面对多版本jQuery如何应用
概要本文通过意在和大家分享一个运营了15年的老旧站点,升级为流行的Bootstrap风格的解决方案。来说明如何让bootstrap运行在各种版本的jQuery环境中。旧站点现状当前站点为运行在IIS 下的ASP.NET站点,重要页面50个,常用页面300个,总共约1000个页面。这些页面服务于销售部的2000多名销售人员。该站点历经15年大大小小无数项目的建设。前端JS插件: 插件情况极其复杂,有来自jQuery-ui库的标准插件,有来自第三方的插件,有的插件第三方已经不再维护,有基于jQuer原创 2020-12-04 15:24:49 · 748 阅读 · 0 评论 -
C#的Attribute和Typescript的装饰器之比较
概要C#的Attribute和Typescript的装饰器都可以实现AOP,以达到优化代码结构的作用。两者都可以在不修改原有代码的基础让,添加新的功能到已有类中,但是却采用了不同的实现方式。本文以一个字符串最大长度的限定的例子,来比较二者的实现方式。概念比较在C#中,通过定义一个类,该类继承Attribute类,来作为作为饰器使用。从而实现对类,类中的属性,方法,方法参数等的装饰。在C#的编译器会先实例化装饰类,再实例化被装饰的内容,这就决定了在该装饰饰器类内部,是无法访问到装饰修饰的对象,所以装饰原创 2020-11-25 18:25:13 · 1197 阅读 · 1 评论 -
Vue 3.0父子组件通信
在Vue 3.0 发布以后,我们基于新的特性,来归纳一下父子组件通信的方式。并且检验一下Vue 2.0中常用的通信方式,如何在Vue 3.0中使用。本文列出了三种通信方式:通过emit函数派发消息父组件通过事件代理获取子组件内容通过vuex定义全局数据设计和实现本文通过一个具体实例来说明具体的通信方式,用户可以将tab数据和初始默认选中的tab-item作为属性传入tabs组件。组件支持按月查询销量,每个月份为一个tab项,每个tab项内包含一个当月的销量数据。点击tab-item的链接,t原创 2020-09-23 18:05:57 · 6214 阅读 · 0 评论 -
Javascript对象深度复制的实现
Javascript对象深度复制本文基于ES5和ES6两个版本的Javascript,分别实现了对象的深度复制。对于不在Javascript对象原型链上的内容,将全部复制到新的对象中。ES5的实现function deepClone(source,target){ var _tar = target || {}; for(var key in source){ if(source.hasOwnProperty(key) && source[key] !=原创 2020-09-09 16:29:28 · 251 阅读 · 0 评论 -
彻底解决Error: Requires Babel “^7.0.0-0“, but was loaded with “6.26.3“. 的问题
彻底解决Error: Requires Babel “^7.0.0-0”, but was loaded with “6.26.3”. 的问题问题产生在babel升级到7以后,按照其官网的要求,安装了babel 7.0相关的包,具体包括@babel/core, @babel/cli, @babel/@babel/preset-env,@babel/plugin-transform-runtime,@babel/plugin-proposal-class-properties, @babel/plugin原创 2020-09-01 16:39:22 · 14397 阅读 · 2 评论