Less 3.0+ 不支持原生 Map,所谓“Map”实为编译期静态伪映射,仅支持 map-get(@m, key) 形式查表,键须为无引号标识符,不支持变量传键、嵌套访问或 JS 交互。

Less 3.0+ 不支持原生 JSON 或 JavaScript 风格的 Map 数据结构,所谓“Map 功能”实际是 map-keys()、map-values()、map-get() 等函数对**伪映射(即括号包裹的键值对列表)**的支持。它不是运行时对象,不能动态构造、不能嵌套访问、也不能序列化——只是一种编译期静态查表机制。
为什么 @colors: (primary: #007bff, success: #28a745) 不是真正 Map
这种写法在 Less 中叫“映射字面量”,本质是语法糖,编译器把它当做一个不可拆解的 token 序列处理。它不支持:
-
map-get(@colors, "primary")→ 报错,键必须是无引号标识符(primary),不能是字符串 -
map-get(@colors, @key)→ 若@key是变量,且值为primary,仍会失败:Less 不做变量求值后再查表 - 嵌套写法如
(light: (primary: #007bff))→map-get(map-get($theme, light), primary)会报错,因为第二层返回的是规则集或空值,不是可再map-get的结构
如何安全地用 map-get() 做主题配置中心
把颜色、间距、断点等配置集中定义为顶层映射,再通过 map-get() 按需提取,是可行的,但必须遵守三原则:
- 所有键名必须是合法 Less 标识符(字母/下划线开头,不含空格、连字符、点号)
- 每个
map-get()调用必须显式写出键名,不能靠变量间接传入 - 避免多层嵌套;若需分主题,改用扁平命名:
@spacing-light-sm: 4px,或用规则集模拟(见下一条)
示例:
立即学习“前端免费学习笔记(深入)”;
@theme: (
color-primary: #007bff,
color-success: #28a745,
spacing-sm: 4px,
spacing-md: 8px
);
.text-primary { color: map-get(@theme, color-primary); }
.mt-sm { margin-top: map-get(@theme, spacing-sm); }
替代方案:用规则集(ruleset)模拟可嵌套的配置对象
当需要类似 $theme.light.colors.primary 的路径式访问时,规则集是唯一可靠方式(Less 3.5+ 支持):
- 定义:
@theme: { light: { colors: { primary: #007bff; }; }; };—— 注意大括号、分号、无逗号 - 访问:
@theme.light.colors.primary→ 编译后直接展开为#007bff - 不能动态拼接键名:
@layer: light; @theme.@{layer}.colors.primary会失败,@{}插值不适用于规则集路径 - 适合静态设计系统配置,不适合运行时切换(毕竟所有分支都在编译期确定)
真正容易被忽略的一点:Less 的“Map”和“规则集”都**无法与 JavaScript 交互**。你在 .less 里定义的 @theme,不会自动变成 CSS 自定义属性,也不会注入到 JS 的 getComputedStyle 中。要打通前后端配置,必须手动导出为 :root { --color-primary: #007bff; } 或生成 JSON 文件供 JS 加载——这一步没有自动化 magic,得自己写脚本或构建插件。


















