Javascript 为什么改变构造函数调用的顺序会导致它发生故障?

Javascript 为什么改变构造函数调用的顺序会导致它发生故障?,javascript,arrays,object,Javascript,Arrays,Object,下面的函数创建了一个计算器,它最初只支持两个数字的加减运算,但可以使用“this.addMethod”进行扩展,以适应其他运算符,如“/”、“*”和“**” 但是,当我通过构造函数(“new”)添加一个新的计算器并向其添加新的操作时,power操作(“**”)只有在首先调用它时才能正常工作 完整代码如下: 函数计算器(){ this.supportedOperators=['+','-']; this.supportedMethods=[ (a,b)=>a+b, (a,b)=>a-b ]; t

下面的函数创建了一个计算器,它最初只支持两个数字的加减运算,但可以使用“this.addMethod”进行扩展,以适应其他运算符,如“/”、“*”和“**”

但是,当我通过构造函数(“new”)添加一个新的计算器并向其添加新的操作时,power操作(“**”)只有在首先调用它时才能正常工作

完整代码如下:

函数计算器(){
this.supportedOperators=['+','-'];
this.supportedMethods=[
(a,b)=>a+b,
(a,b)=>a-b
];
this.calculate=(str)=>{
for(此.supportedOperators的运算符){
if(str.includes(操作员)){
让分隔符=operator.length;//用于“**”运算符
让第一个操作数=str.slice(0,str.indexOf(运算符));
让第二个操作数=str.slice(str.indexOf(运算符)+分隔符);
返回this.supportedMethods[this.supportedOperators.findIndex(item=>item==operator)]
(+第一个操作数,+第二个操作数);
/*检查支持的运算符,然后在操作数上使用它
这里乱七八糟,但我尽了最大努力让它更易读和理解*/
}else console.log(“不支持的操作”);
}
};
this.addMethod=(运算符,方法)=>{
此。支持操作器。推送(操作器);
此.supportedMethods.push(方法);
}
}
让powerCalc=新计算器;
powerCalc.addMethod(“**”,(a,b)=>a**b);//很好
powerCalc.addMethod(“*”,(a,b)=>a*b);
powerCalc.addMethod(“/”,(a,b)=>a/b);
让结果=powerCalc.calculate(“4**3”);//64,应为(也支持其他值)

控制台日志(结果)正如上面的注释所述,问题在于
***
*
运算符都包含“*”符号。建议的解决方案之一是实现
sort()
,以便长度最长的运算符排在第一位

另一个是使用不同的数据结构,我决定使用它。代码如下:

function Calculator() {

  this.methods = {
    "-": (a, b) => a - b,
    "+": (a, b) => a + b
  };

  this.calculate = function(str) {

    let split = str.split(' '), 
      a = +split[0],
      operator = split[1],
      b = +split[2] // split the input string into an array of two operands converted to numbers and an operator

    if (!this.methods[operator] || isNaN(a) || isNaN(b)) {
      return NaN;
    }

    return this.methods[operator](a, b);
  }

  this.addMethod = function(name, func) {
    this.methods[name] = func;
  };
}

let powerCalc = new Calculator;

powerCalc.addMethod("*", (a, b) => a * b);
powerCalc.addMethod("/", (a, b) => a / b);
powerCalc.addMethod("**", (a, b) => a ** b); // the order doesn't matter anymore

let result = powerCalc.calculate("4 ** 3"); 
alert( result ); // 64, as it should be
谢谢大家的投入

还有一条评论指出,问题名称与我遇到的实际问题无关。我会很快编辑它,当我想出一个更好的主意。抱歉给你带来困惑,我才刚开始学习JS。
如果您对如何更好地命名问题有想法,请将其发布在评论中。

正如上面的评论所说,问题在于
***
*
运算符都包含“*”符号。建议的解决方案之一是实现
sort()
,以便长度最长的运算符排在第一位

另一个是使用不同的数据结构,我决定使用它。代码如下:

function Calculator() {

  this.methods = {
    "-": (a, b) => a - b,
    "+": (a, b) => a + b
  };

  this.calculate = function(str) {

    let split = str.split(' '), 
      a = +split[0],
      operator = split[1],
      b = +split[2] // split the input string into an array of two operands converted to numbers and an operator

    if (!this.methods[operator] || isNaN(a) || isNaN(b)) {
      return NaN;
    }

    return this.methods[operator](a, b);
  }

  this.addMethod = function(name, func) {
    this.methods[name] = func;
  };
}

let powerCalc = new Calculator;

powerCalc.addMethod("*", (a, b) => a * b);
powerCalc.addMethod("/", (a, b) => a / b);
powerCalc.addMethod("**", (a, b) => a ** b); // the order doesn't matter anymore

let result = powerCalc.calculate("4 ** 3"); 
alert( result ); // 64, as it should be
谢谢大家的投入

还有一条评论指出,问题名称与我遇到的实际问题无关。我会很快编辑它,当我想出一个更好的主意。抱歉给你带来困惑,我才刚开始学习JS。
如果您对如何更好地命名问题有想法,请将其张贴在评论中。

包含
“**”
的表达式字符串包括
“*”
If(str.includes(operator)){
将使用
运算符运行
成为
*
此问题与构造函数无关。在两个示例中,构造函数
计算器
是在同一点上调用的。您可能应该按运算符长度降序排序,以避免此类问题。(将运算符和方法保留在两个单独的数组中,这当然会使这一点更加困难-您必须按照运算符排序所产生的相同顺序对方法进行排序。或者,首先找到一个更合适的数据结构-将运算符和方法保留在单个“项”中的数据结构),这样您就可以一次按运算符长度对这些项的整个列表进行排序。)当循环首先使用
*
检查字符串时,if正在使条件为真,因为输入
4**3
包含
*
,其中包含
“**”
的表达式字符串包含字符串
“*”
if(str.includes(operator)){
将在
operator
*
的情况下运行。此问题与构造函数无关。在两个示例中,构造函数
计算器
是在同一点上调用的。您可能应该按运算符长度降序排序,以避免此类问题。(将运算符和方法保留在两个单独的数组中,这当然会使这一点更加困难-您必须按照运算符排序所产生的相同顺序对方法进行排序。或者,首先找到一个更合适的数据结构-将运算符和方法保留在单个“项”中的数据结构),这样您就可以一次按运算符长度对这些项的整个列表进行排序。)当循环首先使用
*
检查字符串时,if使条件为真,因为输入
4**3
包含
*