JavaScript使用reduce分组及合并数组的object对象
对象数组示例:var objects = [ {name:'group1', usedCount: 2, color:'red'}, {name:'group1', usedCount: 1, color:'blue'}, {name:'
对象数组示例:var objects = [ {name:'group1', usedCount: 2, color:'red'}, {name:'group1', usedCount: 1, color:'blue'}, {name:'
for...in与其说是迭代,更恰当的说法应该是枚举。其目的是用来枚举object对象的属性,包括对象所继承的属性。有部分人会使用for...in来迭代数组,这是一种误用。以下对使用for...in迭代数组分析。问题一var a = ['a','b']; a[5] = 'e'; for (var x in a
不同的浏览器支持的视频/音频格式有所不同,为了在多个浏览器上兼容视频/音频的播放,需要使用JavaScript检测浏览器所支持的视频/音频格式。HTMLVideoElement和HTMLAudioElement继承于HTMLMediaElement,HTMLMediaElement的canPlayType()方法可以用来判断浏览器是否支持指定的多媒体格式。语法str = aud
普通函数的this普通函数的this是由动态作用域决定,它总指向于它的直接调用者。具体可以分为以下四项:this总是指向它的直接调用者, 例如 obj.func() ,那么func()里的this指的是obj。在默认情况(非严格模式,未使用 'use strict'),如果函数没有直接调用者,this为window在严格模式下,如果函数没有直接调者
要理解Vue实例里this的使用,首先要理解this在JavaScript里的用法,可以参考理解JavaScript普通函数以及箭头函数里使用的this。这是vue文档里的原话:All lifecycle hooks are called with their 'this' context pointing&
thenjs 是一个js的异步控制流程库特点可以像标准的Promise那样,把N多异步回调函数写成一个长长的then链,并且比Promise更简洁自然。因为使用标准Promise的then链,其中的异步函数都必须转换成Promise,Thenjs则无需转换,像使用CallBack一样执行异步函数即可。强大的Error机制,可以捕捉任何同步和异步的异步错误。开启debug模式,可以把每一个then链
CryptoJS只一个JavaScript的加解密的工具包。它支持多种的算法:MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。CryptoJS的安装1、使用npm安装npm install crypto-js2使用Bower安装bower install crypto-jsCryptoJS的使用Cryp
以下是JavaScript使用正则表达式的一个备忘录。测试正则表达式test()方法:用来测试字符串是否满足表达式。let testString = "My test string"; let testRegex = /string/; testRegex.test(testString);测试多个pattern可以使用或操作符(|)来连接多个表达式const regex = /yes|no|ma
我们知道,CKEditor5是一个用MVC架构设计的富文本编辑器。如上图所示,三层分别是:Model,Controller, View首先,第一个问题是schema属于那一层?经过官方文档的初步学习,我们可以看到:editor.model.schema; // -> The model's schema.因此,我们可以得出结论:schema属于模型层:其次我们需
最近在学习CK5,一种最大的感受就是CK5的架构不是很大,但是内容特别多。笔者在学习中,总结出一个浅显的道理,那就是掌握基础知识,对框架宏观把握,学习起来会事半功倍。今天开始初步研究一下CK5的事件系统:在CK5的事件系统中,关键的一个对象被称作Emitter(发射器),Emitter是一个可以发送事件的对象。如何创建一个Emitter,下面的代码创建了一个混合了事件发送的AnyClass类,它实
今天继续学习CK5的事件系统,上一节我们知道了绑定和取消绑定事件的两种方法,知道在一个emitter上一个同名事件可以绑定多个回调函数,自然问题来了,这些函数的执行顺序是怎么样的呢?CK5的事件监听优先级实际上,对于一个同名事件,CK5提供了事件优先级功能,如下代码所示const anyClass = new AnyClass(); anyClass.on( 'eventName', ( even
emitter接口提供了事件代理机制。也就是说指定选择的事件能够被其他的emitter触发。 1、代理指定的事件到另一个emitterlet anyClass = new AnyClass(); let anotherClass = new AnyClass(); let oneClass = new AnyClass(); anotherClass.on('bar',(evt,data
CK5的视图(view.document)不仅是一个Observable和emitter,而且还实现了一个BubblingEmitter,它是由BubblingEmitterMixin实现的。它提供了在虚拟dom机制上的冒泡事件。 它与普通的dom树上的冒泡机制不同。它不会在特定的元素上注册监听器,而是在指定的上下文上注册监听器。这里的上下文,要么是一个元素,要么是虚拟上下文之一,要么是
在CKEditor5中除了事件系统外,还有另一个重要的系统就是可观测对象,俗称Observable对象。此对象的属性是可观测的,一段对象的属性发生改变,将会触发一个事件,监听此事件的代码片段可以做出一些相应的操作。 CK5定义一个可观测对象import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin'
CK5还可以将模板的属性绑定到可观测对象属性,如下代码所示:import {View} from 'ckeditor5/src/ui'; export default class Button extends View { constructor(){ super(); this.type = 'button'; const bind =
前面我们知道了,在CK5中怎么样将一个对象设置成Observable以及Observable在UI中如何使用?属性绑定今天我们来看看如何进行可观测对象的属性绑定和重命名。首先,我们假定有两个Observable对象,所谓绑定就是将一个对象的可观测状态绑定到另一个可观测对象,如下所示:const button = new Button(); const command = editor.comman
最近有空学习了一下angular的基础知识,对于angular的装饰器有了一些理解。其实装饰器并非angular特有的,它是Typescript的语言特性。首先我们看看什么是装饰器 我们先看看Typescript官方的说明:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用 @expression这种形式,expression求值后必
我们在使用RxJs中,知道RxJs的操作分为两类,一类是创建型,比如of(),fromEvent(),from()等,还有一类是操作型,比如map(),filter()。而这两类操作的基础和心是一个叫做Observable的对象,如果对Observable不甚理解,需要快速理解的可以查看这一篇今天我们来学习第一类,尝试着自己实现一次。of()这个操作接收数组参数,返回一个Observable,一旦
我们在使用Observable的时候,常常会涉及到一些操作,比如map(),filter()等,为了理解原理,今天我们在前几节(初步理解RxJs , RxJs——创建型操作 )的基础上,用两种不同的方式实现以上两个函数,希望能给大家提供借鉴。map代码实现废话不说,先来实现mapmap(fn) { return new MyObservable(observer => {
上一节我们实现了map和filter函数,我们将这些函数都挂载在MyObservable对象上,这里存在一个问题,类似map和filter这样的操作型函数很多,所以不可能将他们都挂载在MyObservable对象上,因此,这里出现了第二种实现。 这些操作函数能串联起来的本质就是能够形成嵌套调用,因此我想到了使用pipe,pipe的本质是接收一个 RxJS 操作符的运行结果作为参数,并返回
什么是subject首先我们来理解什么是subject,按照官方的定义:A Subject is a special type of Observable that allows values to be multicasted to many Observers.Subjects are like EventEmitters.从定义我们看出subject就是一种允许发送值到多个观察者的特殊类型的
上一节我们对subject有了初步理解,今天我们继续学习subjectReplaySubject介绍这个ReplaySubject之前,我们说下一种使用场景1、我们创建一个subject2、在应用的某个地方,我们向subject推送值,但此时没有订阅3、在某个时点,有第一个观察者开始订阅4、我们期望观察者能接收之前主题推送的值(可能是全部值或者时其中一个)5、实际上啥都没发生,因为主题不能存储记忆
从前文我们知道,错误处理有两种方式,一种是重新抛出一个错误,另一个是提供一个默认的回调值。今天我们介绍错误处理的另一种方式,先来看看重试。重试策略有一点需要记住,一旦流出现了错误,我们不能恢复它。但是没有什么能阻碍我们订阅其派生类对应的Observable,并且创建一个新的流。这种策略的工作原理是:1、我们将获取输入Observable并且订阅它,这将创建一个新的流。2、如果流没有出错,我们将在输
上一节我们主要介绍了模型中的Position这个关键的类,今天我们开始学习Range这个类。简单来说的话,如果Position表示一个点的话,那么Range是不是可以理解为一条线段呢?这个线段有一个startPostion,endPosition以及线段的长度等属性,我们暂且这么认为,那么我们可以看看Range官方的文档。从文档中看到,Range类有五个属性:Range属性start:Positi
最近在学习CK5的时候,学习到了一个Rect的类,这个类主要提供盒子元素定位时候用到的一些值,比如top、left、right、bottom、width、height。而它的实现主要用到了两个方法,其中一个就是:Element.getBoundingClientRect()Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,该对象提供有关元素大小及其
自React 18开始,ReactDOM.render被废弃,使用React 18会以兼容模式运行旧代码,并且会有类似以下的警告:Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will beh
最近在学习怎么样给网站埋点,举个例子来说,我在文章中有了一些评论的信息,我需要知道这些评论信息是否被点击和查看,一种常用的做法就是在这些标签上绑定点击事件,然后在事件回调函数中向后台发送信息,从而判断这个文章中的评论是否有被点击和查看。今天我将尝试采用另外一种做法,来判断文章中的评论有没有被点击查看过。首先,我们需要知道的是用户在点击评论标签的时候,文章对应的dom是否发生变化?其次,我会用Mut
上一节我们掌握了一些flex布局的基础知识,这一节我们用flex来做一个圣杯布局HTML<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial
所有的Promise对象都有then()方法,这个方法接受两个参数。第一个参数叫做promise fullfilled是调用的函数,也叫做fulfillment处理器;与异步操作的任何相关数据都可以传递给这个函数。第二个参数是当promise被reject的时候调用的函数,也叫做rejection handler;与fullfillment handler类似,与rejection相关的任何异步操
Promise的catch()Promise 还有一个 catch() 方法,当只传递一个rejection处理程序时,它的行为与 then() 相同。 例如,以下 catch() 和 then() 调用在功能上是等效的: const promise = fetch("books.json"); promise.catch(reason => { // rejection
什么是可测试代码我们理解的可测试代码指的是:1、松耦合2、短小的3、可隔离的我们会依照这三个原则来分析,怎么样编写可测试的代码?一般来说,一个函数或者一个功能,如果越复杂,那么实现此功能需要的代码可能就会越多,代码量就会越多,出现潜在Bug的概率就越大。因此,编写可测试代码的第一步就是让函数或者功能保持最小代码量,而保持最小代码量的方法就是让命令(Command)和查询(Query)分离。我们首先
上一节,我们知道了什么是命令,以及什么是查询。今天我们继续前面的例子,来试着将一个功能太多的函数进行命令和查询的分离。 /** * 查询函数(用于设置值并返回) * */ function configure(values) { var config = { docRoot: '/somewhere' }; var
扇出扇出是测量函数直接或者间接依赖的模块或对象的数量。有一个经验上的代码复杂度计算公式就是:(fan_in * fan_out)的平方一些研究表明:复杂度的值与软件变更有98%的相关性。比如:越复杂的函数或者模块,该函数或者模块就越有可能发生Bug。那么扇出的定义到底是什么呢?过程A的扇出是表示过程A的内部流程数量(指挥别人做的)和过程A所更新的数据结构数量(自己做的)之和。扇出就衡量一个函数做多
耦合上一节我们重点关注了扇出的内容,以及用例子说明了如何才能将一个函数或者模块的代码通过重构来达到一个合理的扇出值。今天我们来理解耦合:耦合是关注模块如何组合在一起的,增加子模块或许可以减少扇出的值,但是不能减少原始模块对最初依赖之间的耦合度;本质是将显示依赖变成了间接依赖。虽然今天我们不讲解内聚,但是我们也说说什么是内聚,以及什么是耦合? 内聚是从功能角度来度量模块内的联系,一个好的内
Babel初步认识BabelJS 是一个 JavaScript 转译器,它将新功能转译成旧标准。有了BabelJS,这些功能可以在新旧浏览器上兼容运行。Babeljs 以插件、预设、polyfill 等形式提供了广泛的功能。简而言之,Babeljs 是一个工具集,其中包含所有可用的工具,它可以帮助开发人员使用 ECMA Script 中可用的所有当前功能,而不必担心浏览器将如何支持它。首先,我们需
BabelJS - ES6 代码执行BabelJS 是一个 JavaScript 转译器,它将添加到 JavaScript 的新功能转换为 ES5 或根据给定的预设或插件做出反应。ES5 是最古老的 JavaScript 形式之一,支持在新旧浏览器上运行而不会出现任何问题。在本文的大多数示例中,我们已将代码转换为 ES5。我们已经看到 ES6、ES7 和 ES8 中添加了许多特性,如箭头函数、类、
BabelJS - 使用 Babel 7 设置项目最新版本的 Babel,7 发布,对现有包进行了更改。安装部分与 Babel 6 相同。abel 7 唯一的区别是所有的包都需要用@babel/ 安装,例如@babel/core、@babel/preset-env、@babel/cli、@babel/polyfill 等。这是使用 babel 7 创建的项目设置。1、执行以下命令开始项目设置npm
BabelJS - 将 ES6 功能转换为 ES5在本文以及接下来的文章中,我们将看到 ES6 中添加的特性。我们还将学习如何使用 BabelJS 将功能编译到 ES5。以下是我们将在本章中讨论的各种 ES6 特性Let + ConstArrow FunctionsClassesPromisesGeneratorsDestructuringIteratorsTemplate LiteralstEn
有趣的web-consoleWeb 控制台是一种工具,主要用于记录与网页相关的信息,例如:网络请求、JavaScript、安全错误、警告、CSS 等。它使我们能够通过在页面内容中执行 JavaScript 表达式来与网页交互。log()error()warn()clear()time() and timeEnd()table()count()group() and groupEnd()custom