首页
留言
友情链接
标签页
Search
1
如何使用JavaScript获取和设置CSS root变量值
1,067 阅读
2
中国历史朝代顺序图
671 阅读
3
那些顶级不落俗套的“美好祝福”
532 阅读
4
春和 《江海共余生》
520 阅读
5
hyperf常用命令
409 阅读
分享
Web前端
html&css
javascript
Vue
shopify
shoplazza
后端
ThinkPHP
YII2
服务器端
软件安装
问题合集
故事
诗词
生活
学习
学科
语文
数学
英语
物理
化学
生物
政治
历史
地理
自然
其他
抖音
快手
小视频
随笔
易经
书摘
登录
/
注册
Search
标签搜索
一年级语文
sunshine
累计撰写
160
篇文章
累计收到
15
条评论
首页
栏目
分享
Web前端
html&css
javascript
Vue
shopify
shoplazza
后端
ThinkPHP
YII2
服务器端
软件安装
问题合集
故事
诗词
生活
学习
学科
语文
数学
英语
物理
化学
生物
政治
历史
地理
自然
其他
抖音
快手
小视频
随笔
易经
书摘
页面
留言
友情链接
标签页
搜索到
17
篇与
的结果
2024-08-16
那些顶级不落俗套的“美好祝福”
1.愿祝君如此山水,滔滔岌岌风云起 2.愿如风有信,长与日俱中 3.从今把定春风笑,且作人间长寿仙 4.如花似叶,岁岁年年,共占春风 5.如月之恒,如日之升 6.愿天上人间,占得欢娱,年年今夜 7.但愿长年,故人相与,春朝秋夕
2024年08月16日
532 阅读
8 评论
1 点赞
2024-08-16
那些只知上半句,不知下半句的诗
男儿有泪不轻弹,只是未到伤心处。枝上柳绵吹又少,天涯何处无芳草。朋友之妻不可欺,朋友之夫不可扶。
2024年08月16日
80 阅读
0 评论
0 点赞
2024-08-16
如何用一句古诗夸女生漂亮
不妆艳已绝,无风香自远--宋·苏轼释义:即使沒有华丽的妝容,容貌也非常惊艳了。虽然没有风,身上的香味却能传的很远。众里嫣然通一顾,人间颜色如尘土-清·王国维《蝶恋花》释义:她在人群中回眸一笑。可以让其它女人失去颜色。
2024年08月16日
58 阅读
0 评论
0 点赞
2024-08-16
背下来你也可以惊艳所有人
相处很久,我越来越喜欢你了古文:初见乍欢,久处仍怦然。遇见你是我的幸运古文:金风玉露一相逢,便胜却人间无数。我喜欢你,你却不知道古文:山有木兮木有枝,心悦君兮君不知。在我心中,你是我是最重要的人古文:我见众生皆草木,唯有见你是青山。我单身,我骄傲古文:我自飘零我自狂,犹如野鹤游四方。
2024年08月16日
64 阅读
0 评论
0 点赞
2024-08-13
阅读摘抄
人生要不断进取,任何时候都不能放弃努力。人生没有白走的路,每一步都算数。总有一天,当我们走累的时候,自然会回到我们最熟悉的地方。学习时一生的事情,对待自己喜欢的领域,更该如此。喜欢仅仅是因为未知。可姐姐那么优秀,就像是夏季怒放的向日葵,无论到哪都是阳光般耀眼的存在。原来,花终会盛开,只是,我们要一直向着有光的地方生长。《我的天才女友》里曾说过:世界上存在这样的关系,你最好的朋友就是你最强大的敌人我希望她能过得好,但我不希望她过得比我好。成长总会经历些不可预料的意外,我们无可避免地要去面对。尊严都是自己挣的,那种被别人一议论就被踩到脚底的自尊不值钱。因为天下老板都有一个臭毛病--不喜欢看到员工因为工作之外的事打成一片、其乐融融。爱情需要包容调和,相处间沟通的劳神费力永远不可避免《山河故人》里说,每个人只能陪你走一段路,迟早是要分开的。两个人,在一起舒服就在一起,觉得不爽就痛痛快快谢过对方温情款待,长别离。时间是一种很残酷的东西,它会冲淡能够冲淡的,但也会洗尽铅华帮你留下该留下的。无论我们虎落平阳终陷落魄,还是一朝显赫半生荣华,朋友越来越少,剩下的也越来越重要。这辈子,相遇一场,只要各自安好,联系不联系都不重要。太过在意某件事,他就会变成困住你的枷锁。人就是因为太过于在意别人的看法,听太多的声音才容易迷失自我。我们总是“这山望着那山高”,殊不知,“一方水土养一方人”,命运早已给我们安排了最适合自己的人生风景。我是一个很肤浅的人,很难参透那种历经沧海桑田世事沉浮后的内心宁静,世上哪有这么多刀枪不入的灵魂,能轻易抵挡外界的暴击。婚姻是一座围城,城外的人想进去,城里的人想出来。人在不满自己的同时,就容易羡慕别人。工作之余,跳跳舞,健健身,练练字,追追剧,旅旅游。生活有钱有闲,是当下年轻人最渴望的状态了。人就是这样,城外的想进来,城内的想出去。人总是最自己得不到的东西充满好奇。体制外觉得体制内稳定,体制内觉得体制外自由。我们习惯于追寻自己没有的东西,习惯于羡慕别人有的东西。不好的回忆会在人难受的时候喷涌而出,以为忘记了,却连时间都记得如此清晰,并给已经失望透顶的人雪上加霜。人就是树,该什么季节,就开什么花,结什么果,人也是,该什么年龄段,就做什么事,不要提前预支。人生是我们自己的,和别人比永远比不完。其实我们大多数人,终其一生,满是遗憾。我曾经认为,一个女人的美丽,是完美的脸颊,紧致的皮肤,高挑的个头和傲人的胸脯。而如今我相信,任何一种相貌,都来自灵魂的修行。每个人都是世界上不可复制的唯一,不美,只要后天努力,你一样可以万丈光芒。阿德勒说:幸运的人用童年治愈一生,不幸的人用一生治愈童年。一个欲望不够强烈的人就像心里没有火种一样,很难燃烧自己。很多事情不能假设,唯有经历。茨威格说过:所有命运赠送的礼物,早已在暗中标好了价格。当世界一片漆黑时,保持中立并不能让你独善其身。成长就是不断失去可能性的过程,你想去山顶摘星星,便不可避免地要失去草原和海洋。路走慢一点,反而走得更稳一点了。
2024年08月13日
60 阅读
0 评论
1 点赞
2024-08-06
搞钱最快的 24种方式
第一条 搞钱就是,成本10元的东西,包装一下,卖200
第二条 搞钱就是,懂行的忽悠不懂行的
第三条 搞钱就是,把A平台的货搬到B平台
2024年08月06日
59 阅读
0 评论
1 点赞
2024-07-03
防抖与节流
防抖与节流的区别:虽然防抖和节流都是优化高频率事件的方法,但它们有不同的侧重点:防抖(Debouncing):在特定时间内只执行一次函数,时间段内的重复调用会重新计时。适用于搜索输入、窗口调整大小等事件。节流(Throttling):限制函数在特定时间内执行的次数。适用于滚动事件、鼠标移动等。<script> function debounce(func, wait) { let timeout; return function (...args) { const context = this; clearTimeout(timeout); timeout = setTimeout(() => { func.apply(context, args); }, wait); }; } // 定义需要防抖的函数 function handleResize() { console.log('Window resized'); } // 创建防抖函数,设置等待时间为 300 毫秒 const debouncedResize = debounce(handleResize, 300); // 添加事件监听器 window.addEventListener('resize', debouncedResize); // 定义需要防抖的函数 function handleInput(event) { console.log('Input value:', event.target.value); } // 创建防抖函数,设置等待时间为 500 毫秒 const debouncedInput = debounce(handleInput, 500); // 添加事件监听器 // const inputElement = document.querySelector('input'); // inputElement.addEventListener('input', debouncedInput); // 节流函数实现 function throttle(func, wait) { let timeout; let lastRun = 0; return function (...args) { const context = this; const now = Date.now(); if (now - lastRun >= wait) { lastRun = now; func.apply(context, args); } else { clearTimeout(timeout); timeout = setTimeout(() => { lastRun = Date.now(); func.apply(context, args); }, wait - (now - lastRun)); } }; } // 节流函数使用示例 // 定义需要节流的函数 function handleScroll() { console.log('Scrolled'); } // 创建节流函数,设置等待时间为 200 毫秒 const throttledScroll = throttle(handleScroll, 200); // 添加事件监听器 window.addEventListener('scroll', throttledScroll); </script>
2024年07月03日
78 阅读
0 评论
1 点赞
2023-09-24
唐诗三百首(26-30)
李白《峨眉山月歌》峨眉山月半轮秋,影入平羌江水流。夜发清溪向三峡,思君不见下渝州。大意:高峻的峨眉山前,悬挂着半轮秋月。流动的平羌江上,倒映着精亮月影。夜间乘船出发,离开清溪直奔三峡。想你却难相见,恋恋不舍去向渝州。这是李白初次出四川时创作的一首依恋家乡山水的诗,写诗人在舟中所见的夜景。全诗连用五个地名,通过山月和江水展现了一幅千里蜀江行旅图,语言自然流畅,构思新颖精巧,意境清朗秀美,充分显示了青年李白的艺术天赋。李白《渡荆门送别》渡远荆门外,来从楚国游。山随平野尽,江入大荒流。月下飞天镜,云生结海楼。仍怜故乡水,万里送行舟。大意:我乘舟渡江来到遥远的荆门外,来到战国时期楚国的境内游览。高山渐渐隐去平野慢慢舒展开,江水一片仿佛流进广阔的莽原。波中月影宛如天上飞来的明镜,空中彩云结成绮丽的海市蜃楼。但我还是更爱恋故乡滔滔江水,它奔流不息陪伴着我万里行舟。这首诗是李白在出蜀途中,从荆门渡过长江,前去游览楚国故地的作品。诗中描绘了渡过荆门后的所见所感,表达了作者对故乡的留恋和对自然的赞美之情。李白《独坐敬亭山》众鸟高飞尽,孤云独去闲。相看两不厌,只有敬亭山。大意:众鸟高飞无影无踪,孤云独去自在悠闲。你看我,我看你,彼此之间两不相厌,只有我和眼前的敬亭山了。此诗表面是写独游敬亭山的情趣,而其深含之意则是诗人生命历程中旷世的孤独感。诗人以奇特的想象力和巧妙的构思,赋予山水景物以生命,将敬亭山拟人化,写得十分生动。作者写的是自己的孤独和自己的怀才不遇,但更是自己的坚定,在大自然中寻求安慰和寄托。《独坐敬亭山》是唐代诗人李白创作的一首诗,是表现诗人自己精神世界的佳作。 该诗表面是写独游敬亭山的情趣,而其深含之意则是诗人生命历程中旷世的孤独感。诗人以奇特的想象力和巧妙的构思,赋予山水景物以生命,将敬亭山拟人化,写得十分生动。全诗似乎全是景语,无一情语,然而,由于景是情所造,因而,虽句句是景,却句句是情。李白《登金陵凤凰台》凤凰台上凤凰游,凤去台空江自流。吴宫花草埋幽径,晋代衣冠成古丘。三山半落青天外,二水中分白鹭洲。总为浮云能蔽日,长安不见使人愁。 大意:凤凰台上曾经有凤凰来悠游,凤去台空只有江水依旧奔流。吴国宫殿的鲜花芳草遮没荒凉小径,晋代多少王族已成荒冢古丘。三山云雾中隐现如落青天外,江水被白鹭洲分成两条河流。那些悠悠浮云总是遮蔽太阳的光辉,登高不见长安城,怎么不让人内心沉痛忧郁。——李白《登金陵凤凰台》《登金陵凤凰台》是唐代伟大诗人李白登金陵凤凰台而创作的怀古抒情之作。 《登金陵凤凰台》主要内容为李白从六朝的帝都金陵看到了唐的都城长安,把历史的典故,眼前的景物和诗人自己的感受,交织在一起。表达了深沉的历史感喟与清醒的现实思索。此诗气韵高古,格调悠远,体现了李白诗歌以气夺人的艺术特色。 历代对崔颢《黄鹤楼》的评价都非常高,而对李白《登金陵凤凰台》多有贬低。其实李诗不论是艺术性还是思想性都胜于崔诗,即所谓“青出于蓝,而胜于蓝”。李白《春夜洛城闻笛》谁家玉笛暗飞声,散入春风满洛城。此夜曲中闻折柳,何人不起故园情。 大意:是谁家精美的笛子暗暗地发出悠扬的笛声?随着春风飘扬,传遍洛阳全城。就在今夜的曲中,听到故乡的《折杨柳》,哪个人的思乡之情不会因此而油然而生呢?此诗抒发了诗人客居洛阳夜深人静之时被笛声引起的思乡之情,其前两句描写笛声随春风而传遍洛阳城,后两句写因闻笛而思乡。全诗扣紧一个“闻”字,抒写诗人自己闻笛的感受,合理运用想象和夸张,条理通畅,感情真挚,余韵无穷。《春夜洛城闻笛》是唐代诗人李白创作的七言绝句,出自《全唐诗》。 这首诗是公元734年(唐玄宗开元二十二年)或公元735年(唐玄宗开元二十三年)李白游洛阳时所作。当时李白客居洛城,大概正在客栈里,偶然听到笛声而触发思乡之情,所以写下此诗。该诗抒发了作者客居洛阳夜深人静之时被笛声引起的思乡之情,前两句描写笛声随春风而传遍洛阳城,后两句写因闻笛而思乡。全诗扣紧一个“闻”字,抒写自己闻笛的感受,合理运用想象和夸张,条理通畅,感情真挚,余韵无穷。 谁家玉笛暗飞声,散入春风满洛城。此夜曲中闻折柳,何人不起故园情。
2023年09月24日
152 阅读
0 评论
0 点赞
2023-05-10
《夜的命名术》书摘
1.忽然想到一个问题,如果这是自己人生中最后两个半小时,那自己应该做什么?这个问题其实既严肃又浪漫。因为它是在问你,你人生中最想做,却又还没来得及做、或者不敢做的事情是什么。未表达的爱意,相见却没见的人,想去却没有去的地方,想说却没有说的话,都在答案范畴。这个问题,直问本心。2.他这辈子确实有很多遗憾,也有很多不敢做的事情。但今晚他不需要怯懦与畏惧,只需要勇气。3.当秩序成了混乱的时候,就不得不用混乱来维持秩序,拯救法律了4.所以你要明白啊我的朋友,我们不能用温柔去应对黑暗,要用火。5.命这个字在中华汉字里从来都没有过同音字,或许这本身就暗示着,命只有一条。6.等待和希望,人类的所有智慧都包含在这两个词汇里。7.你知道吗,每个人都有两次生命。第二次生命开始于,你意识到生命只有一次的时候。从那一刻起,你会开始告诉自己时间的重要性,并清楚的意识到,自己曾经虚度了多少时光。8.没有什么东西是一成不变的,因为人心一直在变。9.那一团火像是顷刻间烧尽了前尘往事,从此之后他明白了自己的选择,不需要再自怨自艾,不需要再回头看。余生,尽是前路。10.离群索居者,不是神明,就是野兽。11.青春,就是热血又懵懂的年纪,这个时候你或许会犯一些错,甚至犯很多错。但其实当青春结束的那一刻,你又会发现,原来犯错本身就是青春美好而又灿烂的原因之一。这时的你冲动,跳脱,无畏,但从不后悔。12.千里路途我只陪他一程,从此风雪艳阳我都不再过问。13.人生当如蜡烛一样,从头燃到尾,始终光明14.永远少年。永远赤诚。永远年轻,永远渴望踏上新的征程。15.少年的人生不需要回头,只需要落子无悔的勇气。16.学生时代的友谊最纯洁,很多人其实不明白这个道理,直到大家离开校门,走入人心险恶的社会时才能意识到,原来过去的旧时光里,自己曾拥有过友谊这种世间最宝贵的东西。朋友会为你高兴,为你拼命,在那个肆无忌惮的年代,一起追风,一起做梦。没有什么比这更美好了。17.一个人生下来,从来都不是为别人而活的,愧疚与顾及他人其实是一种负能量,而任性与自我其实是一种被低估的美德。18.牛羊成群,唯猛虎独行。19.是啊,如果技不如人,那就试试用你奋力的人生、战斗的本能、不屈的意志!还有豁出去的勇气!20.一个人喜欢什么样的人,应该由她的喜好来决定,而不是由她的性别来决定,性别是客观存在的事物,它不应该左右一个人的情感。21.我怕看见诚实的人被迫说谎,我怕正直的人被迫弯腰,我怕理想主义者看见理想破碎,我怕听见谎话连篇者的最后一句真话,我怕明哲保身者突然仗义执言,我怕曾遭理想背叛者,最终为理想而死。我怕看见懦夫最后的勇气,还有叛徒的冲锋。22.弱肉强食是自然界的天条,但摒除一些动物属性,文明才之所以称为文明。23.所谓浪漫,是明知不可为而为之,是世间的一切自有与美好,相比这些,情情爱爱反倒落了下乘。24.你说奇怪不奇怪,到了人生最后一刻,想的竟然都不是那些享受过的美好,而是从未得到的遗憾。25.人,性本恶,但向善。26.这个世界从来不检验你准备了什么,而是没准备什么。27.夕阳余晖、云霞绚烂,那是因为它短暂,如果每分每秒都能看到那种景色,也不会觉得漂亮了。28.人这一生之所以有重量,就是因为它是有限的。29.人只有在最后那段时光里完成的心愿,才最无悔。30.路永远是自己的,人世间从来都没有不散的筵席。31.少年时驰骋的风,比黄金都贵啊。32.若再许我少年时,一两黄金一两风!33.人间总有一两风,填我十万八千梦。34.永远少年,这是老爷子人生中最憧憬的,但它说的可不是长命百岁,而是永远年轻、永远赤诚、永远热泪盈眶、永远渴望上路。不要被那些利益所束缚,骑士们天生就是凭借着一腔孤勇,去做这世界上最浪漫的人。35.大家总是嘲笑年轻人的天真、幼稚、理想化,然而正是这一往无前的勇气,才能点燃一片火。总有一天,火会烧起来的。36.这世间最勇敢的人不是无知而无畏,而是知道有多危险,却依然选择战斗的人。37.少年总会走过一些曲折的弯路,被路上的荆棘刺伤,被脚底的石子磨烂,但总有一天他会忽然清醒如初。38.感谢这世界,有剥夺,也有馈赠。39.骑士从来不缺面对死亡的勇气!他们的路,本就伴随着生与死!40.你的人生是一条漫长的旅途,期间会有人来,也会有人走。朝阳。晚霞。那一幕幕风景也都会离你远去。可如果说这世上有什么是能永恒陪伴的,一定是信念。41.唯有信仰与日月亘古不灭。42.当命运给你选择的那一刻,你只需要选择倒下还是站起来,然后剩下的痛苦都不重要了。43.功成不必在我。44.可是你要明白啊我的朋友,我们不能用温柔面对黑暗,要用火。45.骑士的信仰,除了勇气之外还有什么呢?应该还有赤诚。永远不问利益,只问本心的赤诚。46.用白昼命名黑夜。47.一个人总要明白这个世界有多冰冷,然后才会明白自己心里的那点温度是多么重要。你的人生也只有这一条路。走过去,才能活的更精彩。48.痛苦、挫折、不幸,是天才的进身之阶,是信徒的洗礼之水,是弱者的无底深渊。命运只是给你选择,怎么选是你自己的事情。49.自己苦过的人,才能更理解别人的苦。50.辉煌的火光将过去都烧成灰烬。昨日种种,譬如昨日死。今日种种,譬如今日生。51.跳舞的人要不停的练功,他们脚上有伤,膝盖有血,台下哭了一遍又一遍,喊着要放弃也不知道喊了多少次。但登台的那一刻,他穿着绚烂的衣服,身上只剩下优雅与从容。从那一刻起你就该知道,丑小鸭真的可以变成白天鹅,人间真的有童话。可这童话不是别人写给你看的,是你用血与泪,写给自己的。52.生死关到底是什么呢?是在失控的边缘,寻找内心的秩序,然后与这世界交个朋友。53.东风夜放花千树!更吹落,星如雨!54.我过去认为,真正的世界就只有利弊,但后来我发现,当你开始衡量利弊的时候,就已经被这个世界打败了。55.不要让时代的悲哀,成为你的悲哀。56.若我身处这长夜不会自己过去,那就用光芒与白昼重新定义。57.功成不必在我,功成必定有我58.没有流血与牺牲的胜利,一定是虚假的胜利。59.别把最艰难的选择留给别人,要留给自己。如果自己没有希望了,那就把希望留给别人。最危险的地方我去,最艰难的任务我来。只要最后能够胜利,我可以将一切奉献给明天。60.凤箫声动!玉壶光转!一夜鱼龙舞!61.相信奇迹的人,本身就是奇迹。62.如果我没有见过光明,我本可以忍受黑暗。63.人这一辈子是一定会犯错的,但我们所犯过的错误,一定要帮我们成为一个更好的人。64.时间太不经用了,抬头已是半生。65.生活就是这样,成年的过程,大概就是要明白这个世界其实并不以自己为中心。66.年少时,所有人都会做很多很无聊的事情。与赚钱无关,与名利无关。这个时候所有人做事的目的性都不强,傻傻的就很快乐。67.大家心里都有一个英雄,他大概率会是你的父亲。他看着你长大,成为你的目标,让你知道该如何和这个世界相处,并为你遮风挡雨。68.人这一辈子的朋友很多,有时候会走散,有时候会重逢,这都很正常。69.有时候,人生里与朋友离别,并不是彼此吵架了或者闹矛盾了,只是路上走着走着就不见了而已.。70.人不是活一辈子,不是活几年几月几天,而是活那么几个瞬间。71.这世间的权柄都有重量,命运在给予馈赠的时候,早就暗自标好了价码。72.奔跑吧,用绝望都追不上的速度。杀尽仇敌,站在我的肩膀上,看一看那个本该属于你的世界73.不要怕,当你感到恐惧的时候,一定要睁开眼看着恐惧,直到它不再是你的恐惧。74.不会因为有人比你更努力,就让你少获得什么。75.强者恒强就是这个道理,使他们变强的不是一个富裕的家庭,不是一个天生在终点的起跑线,而是誓死要跑到终点的勇气与决心。76.人生不就是这样吗,失败了也要爬起来继续往前走啊77.骑士的初心便是真实与赤诚,真实的面对自己,对世界保持赤诚。所谓真实,就是不矫情、不扭捏、不虚伪、不做作、不被世俗标准绑架。所谓赤诚,便是拳拳之心可昭日月,诚恳、坦白、热烈。78.给你们铁与血,给你们战争与荣誉。79.从此江湖路远,不问归期!80.如果你在战场上没有希望了,那就应该把希望留给别人81.家长会只有真心实意的帮助这个世界,这个世界才会愿意帮助我们。如果世界与命运需要我们在这场浩劫中牺牲,才能证明我们改变世界的真诚,那我不介意自己也成为这牺牲者里的一员。82.新世界需要每个人都杀死曾经懦弱的自己,成为新的英雄。83.我回来了,为了那些回不来的人。84.所有问题在被人提出来时,答案其实就已经写在了过去的时光里。85.从来没有哪个民族像我们一样,如此坚韧不拔,勇敢不屈。86.你只需要给他们一点希望,他们就敢跟在你身后去拯救这个世界。87.应是天仙狂醉!乱把白云揉碎!89.如果我不曾见过光明,我本可以忍受黑暗90.生命太过短暂,人们在最不懂事的时候,挥霍了最宝贵的青春,在渐渐懂事的时候挥霍了中年,然后在晚年才追悔莫及。91.太多人在老了以后喜欢说人生如梦。是的,人生确实像一场大梦一样,一眨眼就过去了。92.有些人变强是为了成为人上人,而他们,是为了让这个世界没有人下人。93.为众人抱薪者,不可使其冻毙于风雪。为众人谋福者,不可使其孤军奋战。为自由开路者,不可使其困顿于荆棘。94.记录真相,虽九死尤未悔
2023年05月10日
211 阅读
0 评论
2 点赞
2022-12-24
Vue3 学习笔记(七)
02-详解接口与类型别名之间区别03-字面量类型和keyof关键字04-类型保护与自定义类型保护05-定义泛型和泛型常见操作06-类型兼容性详解07-映射类型与内置工具类型08-条件类型和infer关键字09-类中如何使用类型详解接口与类型别名之间区别接口接口是一系列抽象方法的声明,是一些方法特征的集合。简单来说,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。接口跟类型别名类似都是用来定义类型注解的,接口是用interface关键字来实现的,如下:interface A { username: string; age: number; } let a: A = { username: 'xiaoming', age: 20 }因为接口跟类型别名功能类似,所以接口也具备像索引签名,可调用注解等功能。interface A { [index: number]: number; } let a: A = [1, 2, 3]; interface A { (): void; } let a: A = () => {}接口与别名的区别那么接口跟类型别名除了很多功能相似外,他们之间也是具备某些区别的。对象类型接口合并接口继承映射类型第一个区别,类型别名可以操作任意类型,而接口只能操作对象类型。第二个区别,接口可以进行合并操作。interface A { username: string; } interface A { age: number; } let a: A = { username: 'xiaoming', age: 20 }第三个区别,接口具备继承能力。interface A { username: string } interface B extends A { age: number } let b: B = { username: 'xiaoming', age: 20 }B这个接口继承了A接口,所以B类型就有了username这个属性。在指定类型的时候,b变量要求同时具备A类型和B类型。第四个区别,接口不具备定义成接口的映射类型,而别名是可以做成映射类型的,关于映射类型的用法后面小节中会详细的进行讲解,这里先看一下效果。type A = { // success [P in 'username'|'age']: string; } interface A { // error [P in 'username'|'age']: string; }字面量类型和keyof关键字字面量类型在TS中可以把字面量作为具体的类型来使用,当使用字面量作为具体类型时, 该类型的取值就必须是该字面量的值。type A = 1; let a: A = 1;这里的A对应一个1这样的值,所以A类型就是字面量类型,那么a变量就只能选择1作为可选的值,除了1作为值以外,那么其他值都不能赋值给a变量。那么字面量类型到底有什么作用呢?实际上字面量类型可以把类型进行缩小,只在指定的范围内生效,这样可以保证值不易写错。type A = 'linear'|'swing'; let a: A = 'ease' // error比如a变量,只有两个选择,要么是linear要么是swing,不能是其他的第三个值作为选项存在。keyof关键字在一个定义好的接口中,想把接口中的每一个属性提取出来,形成一个联合的字面量类型,那么就可以利用keyof关键字来实现。interface A { username: string; age: number; } //keyof A -> 'username'|'age' let a: keyof A = 'username';如果我们利用typeof语法去引用一个变量,可以得到这个变量所对应的类型,如下:let a = 'hello'; type A = typeof a; // string 那么利用这样一个特性,可以通过一个对象得到对应的字面量类型,把typeof和keyof两个关键字结合使用。let obj: { username: 'xiaoming', age: 20 } let a: keyof typeof obj = 'username'类型保护与自定义类型保护类型保护类型保护允许你使用更小范围下的对象类型。这样可以缩小类型的范围保证类型的正确性,防止TS报错。这段代码在没有类型保护的情况下就会报错,如下:function foo(n: string|number){ n.length // error }因为n有可能是number,所以TS会进行错误提示,可以利用类型断言来解决,但是这种方式只是欺骗TS,如果在运行阶段还是可能报错的,所以并不是最好的方式。利用类型保护可以更好的解决这个问题。类型保护的方式有很多种,主要是四种方式:typeof关键字instanceof关键字in关键字字面量类型typeof关键字实现类型保护:function foo(n: string|number){ if(typeof n === 'string'){ n.length // success } }instanceof关键字实现类型保护,主要是针对类进行保护的:class Foo { username = 'xiaoming' } class Bar { age = 20 } function baz(n: Foo|Bar){ if( n instanceof Foo ){ n.username } }in关键字实现类型保护,主要是针对对象的属性保护的:function foo(n: { username: string } | { age: number }){ if( 'username' in n ){ n.username } }字面量类型保护,如下:function foo(n: 'username'|123){ if( n === 'username' ){ n.length } }自定义类型保护除了以上四种方式可以做类型保护外,如果我们想自己去实现类型保护可行吗?答案是可以的,只需要利用is关键字即可, is为类型谓词,它可以做到类型保护。function isString(n: any): n is string{ return typeof n === 'string'; } function foo(n: string|number){ if( isString(n) ){ n.length } }定义泛型和泛型常见操作定义泛型泛型是指在定义函数、接口或者类时,未指定其参数类型,只有在运行时传入才能确定。泛型简单来说就是对类型进行传参处理。type A<T = string> = T //泛型默认值 let a: A = 'hello' let b: A<number> = 123 let c: A<boolean> = true这里可以看到通过<T>来定义泛型,还可以给泛型添加默认值<T=string>,这样当我们不传递类型的时候,就会已string作为默认的类型进行使用。泛型还可以传递多个,实现多泛型的写法。type A<T, U> = T|U; //多泛型在前面我们学习数组的时候,讲过数组有两种定义方式,除了基本定义外,还有一种泛型的写法,如下:let arr: Array<number> = [1, 2, 3]; //自定义MyArray实现 type MyArray<T> = T[]; let arr2: MyArray<number> = [1, 2, 3];泛型在函数中的使用:function foo<T>(n: T){ } foo<string>('hello'); foo(123); // 泛型会自动类型推断泛型跟接口结合的用法:interface A<T> { (n?: T): void default?: T } let foo: A<string> = (n) => {} let foo2: A<number> = (n) => {} foo('hello') foo.default = 'hi' foo2(123) foo2.default = 123泛型与类结合的用法:class Foo<T> { username!: T; } let f = new Foo<string>(); f.username = 'hello'; class Foo<T> { username!: T } class Baz extends Foo<string> {} let f = new Baz() f.username = 'hello'有时候也会对泛型进行约束,可以指定哪些类型才能进行传递:type A = { length: number } function foo<T extends A>(n: T) {} foo(123) // error foo('hello')通过extends关键字可以完成泛型约束处理。类型兼容性详解类型兼容性类型兼容性用于确定一个类型是否能赋值给其他类型。如果是相同的类型是可以进行赋值的,如果是不同的类型就不能进行赋值操作。let a: number = 123; let b: number = 456; b = a; // success let a: number = 123; let b: string = 'hello'; b = a; // error当有类型包含的情况下,又是如何处理的呢?let a: number = 123; let b: string | number = 'hello'; //b = a; // success a = b; // error变量a是可以赋值给变量b的,但是变量b是不能赋值给变量a的,因为b的类型包含a的类型,所以a赋值给b是可以的。在对象类型中也是一样的处理方式,代码如下:let a: {username: string} = { username: 'xiaoming' }; let b: {username: string; age: number} = { username: 'xiaoming', age: 20 }; a = b; // success b = a; // errorb的类型满足a的类型,所以b是可以赋值给a的,但是a的类型不能满足b的类型,所以a不能赋值给b。所以看下面的例子就明白为什么这样操作是可以的。function foo(n: { username: string }) {} foo({ username: 'xiaoming' }) // success foo({ username: 'xiaoming', age: 20 }) // error let a = { username: 'xiaoming', age: 20 } foo(a) // success这里把值存成一个变量a,再去进行传参就是利用了类型兼容性做到的。映射类型与内置工具类型映射类型可以将已知类型的每个属性都变为可选的或者只读的。简单来说就是可以从一种类型映射出另一种类型。这里我们先要明确一点,映射类型只能用类型别名去实现,不能使用接口的方式来实现。先看一下在TS中是如何定义一个映射类型的。type A = { username: string age: number } type B<T> = { [P in keyof T]: T[P] } type C = B<A>这段代码中类型C与类型A是完全一样的,其中in关键字就类似于一个for in循环,可以处理A类型中的所有属性记做p,然后就可以得到对应的类型T[p]。那么我们就可以通过添加一些其他语法来实现不同的类型出来,例如让每一个属性都是只读的,可以给每一项前面添加readonly关键字。type B<T> = { readonly [P in keyof T]: T[P] }内置工具类型每次我们去实现这种映射类型的功能是非常麻烦的,所以TS中给我们提供了很多常见的映射类型,这些内置的映射类型被叫做,内置工具类型。Readonly就是跟我们上边实现的映射类型是一样的功能,给每一个属性做成只读的。type A = { username: string age: number } /* type B = { readonly username: string; readonly age: number; } */ type B = Readonly<A>Partial可以把每一个属性变成可选的。type A = { username: string age: number } /* type B = { username?: string|undefined; age?: number|undefined; } */ type B = Partial<A>Pick可以把某些指定的属性给筛选出来。type A = { username: string age: number gender: string } /* type D = { username: string; age: number; } */ type D = Pick<A, 'username'|'age'>Record可以把字面量类型指定为统一的类型。/* type E = { username: string; age: string; } */ type E = Record<'username'|'age', string>Required可以把对象的每一个属性变成必选项。type A = { username?: string age?: number } /* type B = { username: string; age: number; } */ type B = Required<A>Omit是跟Pick工具类相反的操作,把指定的属性进行排除。type A = { username: string age: number gender: string } /* type D = { gender: string } */ type D = Omit<A, 'username'|'age'>Exclude可以排除某些类型,得到剩余的类型。// type A = number type A = Exclude<string | number | boolean, string | boolean>我们的内置工具类型还有一些,如:Extract、NonNullable、Parameters、ReturnType等,下一个小节中将继续学习剩余的工具类型。条件类型和infer关键字在上一个小节中,学习了Exclude这个工具类型,那么它的底层实现原理是怎样的呢?type Exclude<T, U> = T extends U ? never : T;这里可以看到Exclude利用了 ? : 的写法来实现的,这种写法在TS类型中表示条件类型,让我们一起来了解下吧。条件类型条件类型就是在初始状态并不直接确定具体类型,而是通过一定的类型运算得到最终的变量类型。type A = string type B = number | string type C = A extends B ? {} : []条件类型需要使用extends关键字,如果A类型继承B类型,那么C类型得到问号后面的类型,如果A类型没有继承B类型,那么C类型得到冒号后面的类型,当无法确定A是否继承B的时候,则返回两个类型的联合类型。那么大多数情况下,条件类型还是在内置工具类型中用的比较多,就像上面的Exclude方法,下面就让我们一起看一下其他内置工具类型该如何去用吧。Extract跟Exclude正好相反,得到需要筛选的类型。// type Extract<T, U> = T extends U ? T : never -> 实现原理 // type A = string type A = Extract<string | number | boolean, string>NonNullable用于排除null和undefined这些类型。//type NonNullable<T> = T extends null | undefined ? never : T; -> 实现原理 //type A = string type A = NonNullable<string|null|undefined>Parameters可以把函数的参数转成对应的元组类型。type Foo = (n: number, m: string) => string //type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never; -> 实现原理 // type A = [n: number, m: string] type A = Parameters<Foo> 在Parameters方法的实现原理中,出现了一个infer关键字,它主要是用于在程序中对类型进行定义,通过得到定义的p类型来决定最终要的结果。ReturnType可以把函数的返回值提取出类型。type Foo = (n: number, m: string) => string //type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any; -> 实现原理 //type A = string type A = ReturnType<Foo>这里也通过infer关键字定义了一个R类型,对应的就是函数返回值的类型。通过infer关键字可以在泛型之外也可以定义类型出来。下面再利用infer来实现一个小功能,定义一个类型方法,当传递一个数组的时候返回子项的类型,当传递一个基本类型的时候就返回这个基本类型。type A<T> = T extends Array<infer U> ? U : T // type B = number type B = A<Array<number>> // type C = string type C = A<string>这里的U就是自动推断出的数组里的子元素类型,那么就可以完成我们的需求。类中如何使用类型本小节主要讲解在类中如何使用TS的类型,对于类的一些功能使用方式,例如:类的修饰符、混入、装饰器、抽象类等等并不做过多的介绍。类中定义类型属性必须给初始值,如果不给初始值可通过非空断言来解决。class Foo { username!: string; }给初始值的写法如下:class Foo { //第一种写法 //username: string = 'xiaoming'; //第二种写法 // username: string; // constructor(){ // this.username = 'xiaoming'; // } //第三种写法 username: string; constructor(username: string){ this.username = username; } }类中定义方法及添加类型也是非常简单的。class Foo { ... showAge = (n: number): number => { return n; } }类使用接口类中使用接口,是需要使用implements关键字。interface A { username: string age: number showName(n: string): string } class Foo implements A { username: string = 'xiaoming' age: number = 20 gender: string = 'male' showName = (n: string): string => { return n } }在类中使用接口的时候,是一种类型兼容性的方式,对于少的字段是不行的,但是对于多出来的字段是没有问题的,比如说gender字段。类使用泛型class Foo<T> { username: T; constructor(username: T){ this.username = username; } } new Foo<string>('xiaoming');继承中用的也比较多。class Foo<T> { username: T; constructor(username: T){ this.username = username; } } class Bar extends Foo<string> { }最后来看一下,类中去结合接口与泛型的方式。interface A<T> { username: T age: number showName(n: T): T } class Foo implements A<string> { username: string = 'xiaoming' age: number = 20 gender: string = 'male' showName = (n: string): string => { return n } }了解类型中接口与类型别名之间的区别,及各种使用方式掌握什么是泛型与泛型的应用场景,以及与其他语法的结合使用了解了类型的一些高级用法,如:类型保护、类型兼容性了解了类型的一些高级语法,如:映射类型、条件类型全面学习TS中内置的工具类型,如: Partial、Readonly …等
2022年12月24日
48 阅读
0 评论
0 点赞
1
2