正确认识typescript中的泛型
泛型介绍软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
设想这样一个场景,你想设计一个函数,函数有两个参数,并且这两个参数的类型是相同的,也就是说第一个参数如果传string类型,那么要求第二个参数也必须是string类型的,如果第一个参数是number类型的,那么第二个参数也必须是number类型的,那么怎么做到呢?我们不妨先使用JavaScript来声明此函数试一试:
12345678// js声明函数export function addUseJS(a, b) { return [a, b]}// 使用addUseJS(1, 'tom')addUseJS('tom', 'jery')
如此做法,并不能达到我们的要求,你可能会想 ...
react+typescript正确的开发姿势之函数式组件
函数式组件声明使用typescript正确的声明react函数式组件是通常有三种:直接声明、React.FC 和 PropsWithChildren。
直接声明直接声明函数式组件的code如下:
123456789101112131415161718import React from 'react';type HomePropsType = { name: string; age: number; children?: React.ReactNode;}const Home = (props: HomePropsType) => { return ( <div> 这是home组件 </div> )}export default Home;
使用 React.FC 声明话不多说,直接上code:
1234567891011121314151617import React, { FC } from ...
JavaScript原型之对象属性设置与屏蔽
前言JavaScript和面向类的语言不同,在ES6出现之前,它其实并没有类来作为对象的抽象模式,所以在描述对象中不免会遇到一个特别的词语,没错就是原型prototype,今天我们讨论的主角也是它,今天我们就来讨论JavaScript原型中的冰山一角。
三道面试题让我们先来看三道面试题,慢慢的打开你的视野:先列出三道题目都会用到的对象objProto:
1const objProto = {}
123456// 题目一objProto.a = 23const obj = Object.create(objProto)obj.a = 24console.log(obj.a)console.log(obj.hasOwnProperty('a'))
123456789101112// 题目二// 设置objProto对象的a属性为只读属性Object.defineProperty(objProto, 'a', { enumerable: true, configurable: true, value: 23, wri ...
CORS缓存options预检请求
CORS缓存options预检请求增加响应头Access-Control-max-age即可,这样在一定的时间内,后续请求就不会再去发options预检请求了。
Javascript错误捕获
同步代码错误捕获try,carch123456try { const a = 1, b = 2 let c = a + b} catch(err) { console.error(err)}
Promise错误捕获unhandledrejection1234567new Promise((resolve, reject) => { reject(3)})window.addEventListener("unhandledrejection", function(e) { console.error(e)}, true);
总结12345678910111213window.addEventListener('error', (err)=>{ console.error(err)}, true);window.addEventListener("unhandledrejection", function( ...
查看git的某个分支是基于哪个分支拉的
前言在使用git管理代码仓库的时候,经常会遇见一件头疼的事情,就是随着项目的持续迭代,git的分支越拉越多,这时候很容易造成分支管理的混乱,比如你在分支A开发功能,然后改bug需要切换到另一个分支B,切来切去,就会产生混乱。这时候如果能理清各个分支之间的关系就很好办了,比如分支A来自哪里,分支B又来自哪个分支拉出来的。今天告诉你答案,只需要一行代码就可以知道某个分支是基于哪个分支拉出来的,请看:
1git reflog --date=local | grep <branchname>
这个问题最原始的出处是StackOverflow,可以看看这个问题,看完你就懂了How to determine when a Git branch was created?
axios连续请求同一个接口的时候取消前一个请求
写在前面使用axios怎样在连续请求同一个接口时,取消前面的请求,通俗一点来讲就是对接口请求做了个“防抖”的操作。场景:比如现在页面上有个列表查询的按钮,当用户在一秒钟之内,多次点击这个按钮时,那么接口此接口请求会发生多次,前一个接口请求结果还未返回就进行了下一次请求,这样做不但会造成资源的浪费,同时还会加重服务端的压力,怎样避免这样的操作呢?此时,我们只需要在下一个接口发出时,取消前面这个一模一样的接口的请求即可。
幸运的是axios给我们提供了这样的一个骚操作:cancelToken。
话不多说,直接上code:
1234567891011121314151617181920212223242526272829303132333435363738394041424344import axios from 'axios'const http = axios.create()const Cancel = axios.CancelTokenlet httpPending = []function removeHttpPending(config) { ...
vue踩坑之eventBus.多次触发的问题
写在前面记录一下自己使用vue踩过的坑,希望别人看到能避免如此踩坑。先描述问题:假设有两个非父子组件A和组件B,组件A的data中绑定的某个值变化时,通知组件B需要做某些操作,代码如下:
123// 组件Athis.value = 1eventBus.$emit('getSomething', this.value)
123456// 组件Bcreated() { eventBus.$on('getSomething', val => { console.log(val) })}
我们会发现,当组件A已经触发了事件getSomething的时候,第一次切换到组件B时,控制台会打印一次value的值,也就是1;但是当第二次切换到组件B时,会打印两次1,第三次会打印三次,如此累加,这样就会导致很多问题。
解决方法:法一:在每次$on之前调用$off卸载掉事件,如下:
1234567// 组件Bcreated() { eventBus.$off('getSomething' ...
node爬虫入门
1. 爬取接口数据使用http,axios等爬取api接口数据,for example:
12345678const axios = require('axios')const fs = require('fs');(async function () { const { data } = await axios.get('https://api.juejin.cn/user_api/v1/author/recommend?category_id=&cursor=0&limit=20') console.log(data, 996) fs.writeFileSync('./data.json', JSON.stringify(data))})()
2. 爬取html页面有些页面是服务端渲染的,很多数据并不是通过api接口获取的,此时爬虫api接口是无法拿到想要的数据的,此时可以使用request、crawl等爬取整个html页面,然后再从中寻找 ...
记录开发过程中一些常用的正则
123456789101112131415161718192021222324252627282930313233343536373839404142alphabets: /^[A-Za-z]+$/ bankAccount: /^([1-9]{1})(\d{15}|\d{16}|\d{18})$/ currency: /^(([1-9]\d*)|0)(\.\d{0,2})?$/ email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ identity: /^\d& ...