JavaScript 中的模式匹配?
Pattern matching in JavaScript?
我需要在 JavaScript 中创建一个变量并根据条件为其分配值。这有效但感觉有点冗长:
const color = (() => {
switch (type) {
case "primary":
return CONSTANTS.colors.primary;
case "secondary":
return CONSTANTS.colors.secondary;
case "tertiary":
return CONSTANTS.colors.tertiary;
case "positive":
return CONSTANTS.colors.positive;
case "negative":
return CONSTANTS.colors.negative;
case "disabled":
return CONSTANTS.colors.disabled;
default:
throw new Error("A backgroundColor condition was missed");
}
})();
我正在尝试做的是 "pattern matching" 吗?我读到 JavaScript 确实有这个功能,但我不太确定它是什么。
上面的代码有没有更简洁的写法?我可以有很多 if
语句,但这感觉更混乱并且要求变量是 let
而不是 const
。
let color:
if (type === "primary") {
color = CONSTANTS.colors.primary;
} else if(type === "secondary") {
color = CONSTANTS.colors.secondary;
} else if(type === "tertiary") {
color = CONSTANTS.colors.tertiary;
} else if(type === "secondary") {
color = CONSTANTS.colors.secondary;
} else if(type === "positive") {
color = CONSTANTS.colors.positive;
} else if(type === "negative") {
color = CONSTANTS.colors.negative;
} else if(type === "disabled") {
color = CONSTANTS.colors.disabled;
}
解决您问题的最简单方法是检查对象 CONSTANTS.colors
中是否定义了 type
。如果你想通过变量访问一个属性,你需要使用括号注解。括号内的所有内容都被评估为表达式(因此 type
是一个变量,'type'
是字符串值)。因此,object.type
returns 与 object['type']
.
的值相同
let color = null;
if (typeof CONSTANTS.colors[type] !== 'undefined') {
color = CONSTANTS.colors[type];
} else {
throw new Error('A backgroundColor condition was missed');
}
console.log(color);
您也可以先检查对象中是否定义了键 Object.keys()
和 includes()
:
let color = null;
if (Object.keys(CONSTANTS.colors).includes(type)) {
color = CONSTANTS.colors[type];
} else {
throw new Error('A backgroundColor condition was missed');
}
console.log(color);
如果你想支持 IE11,你cannot use .includes()
。使用 .indexOf(type) !== -1
而不是 .includes(type)
.
您正在寻找property accessor:
color = CONSTANTS.colors[type];
模式匹配通常是指匹配传递给函数的参数:测试它们是否匹配特定的 "pattern"。例如,模式匹配可能允许您编写一个函数,该函数在 "two different ways" 中接受一个整数参数,一个传入的参数是 0
,另一个传入的参数不是 0
("otherwise" 案例)。 Switch 语句有点类似于这种类型的分支逻辑,但与 Haskell 等纯函数式语言不同,并且对您的目标没有多大帮助。
换成这样怎么样?
const myColor = CONSTANTS["colors"][type];
if(typeof myColor !== 'undefined') {
color = myColor;
} else {
throw new Error("A backgroundColor condition was missed");
}
您的代码的简单替换是
const color = (() => {
const color = CONSTANTS.colors[type];
if (!color) {
throw new Error("A backgroundColor condition was missed");
}
return color;
}
})();
不,那不是模式匹配。
我认为引入一个保存颜色值的枚举是明智的。
var ColorType = {
Primary: "primary",
Secondary: "secondary",
Tertiary: "tertiary,
...
};
然后你可以在 switch case 中使用这个枚举,你将避免拼写错误和直接引用字符串。
我认为这将使代码不那么冗长且不易出错。
您可以使用 属性 名称作为方括号中的字符串来访问对象的 属性。
(此示例不包括您在 switch 语句中使用的错误捕获,但您可以添加它。)
const CONSTANTS = {
colors: {
primary: "blue",
secondary: "yellow"
}
}
function getColor(myPropName){
// Pass dynamic property names like this
return CONSTANTS.colors[myPropName];
}
console.log(getColor("secondary"));
我需要在 JavaScript 中创建一个变量并根据条件为其分配值。这有效但感觉有点冗长:
const color = (() => {
switch (type) {
case "primary":
return CONSTANTS.colors.primary;
case "secondary":
return CONSTANTS.colors.secondary;
case "tertiary":
return CONSTANTS.colors.tertiary;
case "positive":
return CONSTANTS.colors.positive;
case "negative":
return CONSTANTS.colors.negative;
case "disabled":
return CONSTANTS.colors.disabled;
default:
throw new Error("A backgroundColor condition was missed");
}
})();
我正在尝试做的是 "pattern matching" 吗?我读到 JavaScript 确实有这个功能,但我不太确定它是什么。
上面的代码有没有更简洁的写法?我可以有很多 if
语句,但这感觉更混乱并且要求变量是 let
而不是 const
。
let color:
if (type === "primary") {
color = CONSTANTS.colors.primary;
} else if(type === "secondary") {
color = CONSTANTS.colors.secondary;
} else if(type === "tertiary") {
color = CONSTANTS.colors.tertiary;
} else if(type === "secondary") {
color = CONSTANTS.colors.secondary;
} else if(type === "positive") {
color = CONSTANTS.colors.positive;
} else if(type === "negative") {
color = CONSTANTS.colors.negative;
} else if(type === "disabled") {
color = CONSTANTS.colors.disabled;
}
解决您问题的最简单方法是检查对象 CONSTANTS.colors
中是否定义了 type
。如果你想通过变量访问一个属性,你需要使用括号注解。括号内的所有内容都被评估为表达式(因此 type
是一个变量,'type'
是字符串值)。因此,object.type
returns 与 object['type']
.
let color = null;
if (typeof CONSTANTS.colors[type] !== 'undefined') {
color = CONSTANTS.colors[type];
} else {
throw new Error('A backgroundColor condition was missed');
}
console.log(color);
您也可以先检查对象中是否定义了键 Object.keys()
和 includes()
:
let color = null;
if (Object.keys(CONSTANTS.colors).includes(type)) {
color = CONSTANTS.colors[type];
} else {
throw new Error('A backgroundColor condition was missed');
}
console.log(color);
如果你想支持 IE11,你cannot use .includes()
。使用 .indexOf(type) !== -1
而不是 .includes(type)
.
您正在寻找property accessor:
color = CONSTANTS.colors[type];
模式匹配通常是指匹配传递给函数的参数:测试它们是否匹配特定的 "pattern"。例如,模式匹配可能允许您编写一个函数,该函数在 "two different ways" 中接受一个整数参数,一个传入的参数是 0
,另一个传入的参数不是 0
("otherwise" 案例)。 Switch 语句有点类似于这种类型的分支逻辑,但与 Haskell 等纯函数式语言不同,并且对您的目标没有多大帮助。
换成这样怎么样?
const myColor = CONSTANTS["colors"][type];
if(typeof myColor !== 'undefined') {
color = myColor;
} else {
throw new Error("A backgroundColor condition was missed");
}
您的代码的简单替换是
const color = (() => {
const color = CONSTANTS.colors[type];
if (!color) {
throw new Error("A backgroundColor condition was missed");
}
return color;
}
})();
不,那不是模式匹配。
我认为引入一个保存颜色值的枚举是明智的。
var ColorType = {
Primary: "primary",
Secondary: "secondary",
Tertiary: "tertiary,
...
};
然后你可以在 switch case 中使用这个枚举,你将避免拼写错误和直接引用字符串。 我认为这将使代码不那么冗长且不易出错。
您可以使用 属性 名称作为方括号中的字符串来访问对象的 属性。
(此示例不包括您在 switch 语句中使用的错误捕获,但您可以添加它。)
const CONSTANTS = {
colors: {
primary: "blue",
secondary: "yellow"
}
}
function getColor(myPropName){
// Pass dynamic property names like this
return CONSTANTS.colors[myPropName];
}
console.log(getColor("secondary"));