发布日期:2026-01-26 23:08 点击次数:121

Flutter为啥不用JS而选Dart?,JS明明到处都是,Dart却冷门到没人聊,它真有那么不可替代?
最近在学Flutter,翻文档时一直纳闷:为啥非用Dart?JS不是早就在浏览器里跑得飞起吗?连React Native都靠JS,Flutter偏不走这条路。问了几个前端朋友,有人说“Google想推自家语言”,有人说“就是折腾”,但翻了几遍Flutter官网和Dart的更新日志,发现不是这么回事。它真不是硬塞,是真有硬需求。
Dart最早是2011年Google搞的,想取代JS。结果Chrome以外没一个浏览器愿意内置Dart VM,JS自己又越跑越快,TypeScript还把类型加进去了。那会儿Dart几乎是凉透了。直到2015年Sky项目(后来改名Flutter)重启,Dart才翻盘。这次不是冲着网页去的,而是冲着手机屏幕上的每一帧60fps去的。团队直接把Dart编译器、VM、语法全重调了一遍,专供UI引擎用。

热重载是真的快。改一行代码,手机上UI秒变,连App都不用重启。这靠的是JIT编译——边跑边编,边改边试。但发布时不能这么玩,否则启动慢、耗电高。Dart这时候切到AOT模式,提前把代码打包成原生机器码,安卓iOS直接执行,没中间层。JS做不到这点,V8再快,lol投注app也得靠JS引擎解释,React Native还得过一层桥接,数据来回传,一卡就掉帧。
UI写法差别也大。Flutter里一个按钮、一个列表,全是Dart对象。条件显示标题?直接`if (showTitle) Text('Hi')`,写在children列表里就行。不用切到JSX、不用写`{showTitle &&
空安全也不是噱头。Dart 2.12开始,变量默认不为空,写错会直接报错,不是等App闪退了才告诉你“Cannot read property 'xxx' of null”。TypeScript也能标nullable,但它是加在JS上面的,运行时还是可能出错。Dart是从底子上堵死的。

内存管理也偷偷优化了。Flutter每帧都在造Widget、删Widget,对象生灭特别快。Dart VM用分代GC,开云新对象放“年轻代”,秒杀回收;老对象挪到“老年代”,慢慢清。不像JS V8,GC一来,哪怕只停16ms,也够丢一帧了。
还有个细节很多人忽略:Dart的isolate。它不像JS的Web Worker要靠postMessage传数据,isolate之间不共享内存,传的是拷贝后的值。Flutter引擎直接调Dart代码,不经过桥、不转JSON、不走序列化。线程调度干净利落,帧率稳。
JS不是不行,是定位不一样。它天生为网页服务,要兼容二十年的老代码,要跑在各种设备的浏览器里。而Dart从Flutter开始,就只干一件事:让UI代码在不同平台上跑得和原生一样顺。它不需要支持`document.getElementById`,不需要模拟DOM,也不用管IE。轻装上阵,反而跑得更快。

Dart这几年改得挺实在。Dart 3加了records、模式匹配,写数据处理不那么啰嗦了。WebAssembly也在测,以后说不定能跑在浏览器里干高性能活。但它没去抢JS的生态,没做npm那样的包海,就专注把UI这摊事做稳。
社区小是事实。Stack Overflow上问Dart的人少,GitHub上Star也没React多。可真写起Flutter项目,报错信息清楚,重构不踩坑,发版不懵,团队新人上手两周就能改页面逻辑。这不是玄学,是语言和框架咬合得紧。
Fuchsia系统用Dart写核心模块,Flutter Web和桌面端也越跑越稳。Firebase后台和Flutter前段用同一套类型定义,传数据几乎不用写转换逻辑。这不是凑巧,是设计出来的。

学完这些,我倒不觉得Dart多酷,只是明白了它为什么存在。它不靠热闹活,靠解决问题活。JS解决“怎么让网页动起来”,Dart解决“怎么让界面不卡、不崩、不猜错”。
Flutter选Dart,不是跟风,也不是赌气。是先想清楚要什么,再找最配的工具。
就这点。
