-1

我目前正在研究 codewars kata(将 RGB 数字(0-255)转换为十六进制),并在尝试提高代码的可读性时遇到了一些有趣的事情。我想构造一个全局函数来处理局部变量,但是当我尝试运行代码时,它会在“j”变量(也可能是“i”变量)上引发未定义的错误。下面的代码:

function rgb(r, g, b){
  let x
  let y
  let z
  function conversion(){
    switch(j) {
            case 10:
              j = 'A'
              break
            case 11:
              j = 'B'
              break
            case 12:
              j = 'C'
              break
            case 13:
              j = 'D'
              break
            case 14:
              j = 'E'
              break
            case 15:
              j = 'F'
          }
          switch(i) {
            case 10:
              i = 'A'
              break
            case 11:
              i = 'B'
              break
            case 12:
              i = 'C'
              break
            case 13:
              i = 'D'
              break
            case 14:
              i = 'E'
              break
            case 15:
              i = 'F'
          }
  }
  if (r <= 0) {
    x = '00'
  } else if (r >= 255) {
      x = 'FF'
    } else {
        let i = Math.floor(r / 16)
        let j = Math.floor(r - i * 16)
        conversion()
        x = i.toString() + j.toString()
      }
  if (g <= 0) {
    y = '00'
  } else if (g >= 255) {
      y = 'FF'
    } else {
        let i = Math.floor(g / 16)
        let j = Math.floor(g - i * 16)
        conversion()
        y = i.toString() + j.toString()
      }
  if (b <= 0) {
    z = '00'
  } else if (b >= 255) {
      z = 'FF'
    } else {
        let i = Math.floor(b / 16)
        let j = Math.floor(b - i * 16)
        conversion()
        z = i.toString() + j.toString()
      }
  return x + y + z
}

如您所见,最好使用“转换”功能,而不是复制粘贴所有代码三次。关于这个话题的任何想法?提前致谢。

4

3 回答 3

1

let用和声明的变量const是块作用域的。您当前的设置不起作用,因为i并且j未在任何conversion' 周围块中声明。

虽然您可以(开始)通过在外部函数体中声明i和来修复它:j

function rgb(r, g, b){
  let x
  let y
  let z
  let j;
  let i;
  function conversion(){

最好有conversion简单return的转换值,并将转换后的值分配给ior j。您还可以通过创建另一个用于转换 、 和 参数的函数来显着减少其余代码的重复性rg然后b调用该函数 3 次,而不是复制粘贴相同类型的东西 3 次。

另请注意,要找出一个的位置,您可以对数字使用模运算符%,而不必从 floored 中减去i

function rgb(r, g, b) {
  // parameter should be 0-15
  function convertToSingleHexDigit(num) {
    return num <= 9
      ? String(num)
      : String.fromCharCode(55 + num); // 65 corresponds to A, 66 corresponds to B, etc
  }
  // parameter should be 0-255
  function convertNum(num) {
    const i = convertToSingleHexDigit(Math.floor(num / 16));
    const j = convertToSingleHexDigit(Math.floor(num % 16));
    return i + j;
  }
  return convertNum(r) + convertNum(g) + convertNum(b);
}
console.log(rgb(255, 255, 255));
console.log(rgb(100, 200, 100));

于 2020-01-10T02:18:44.927 回答
1

由于您声明了iand jlet它们的范围就是else您声明它们的块。由于conversion()未在这些块中定义,因此无法访问变量。

您可以在函数顶部声明变量,然后在else块中分配它们。然后它们将在函数内的任何范围内,包括嵌套conversion()函数。

但最好只使它们成为函数参数和返回值。

function rgb(r, g, b){
  let x
  let y
  let z
  function conversion(){
    switch(j) {
            case 10:
              j = 'A'
              break
            case 11:
              j = 'B'
              break
            case 12:
              j = 'C'
              break
            case 13:
              j = 'D'
              break
            case 14:
              j = 'E'
              break
            case 15:
              j = 'F'
          }
          switch(i) {
            case 10:
              i = 'A'
              break
            case 11:
              i = 'B'
              break
            case 12:
              i = 'C'
              break
            case 13:
              i = 'D'
              break
            case 14:
              i = 'E'
              break
            case 15:
              i = 'F'
          }
    return [i, j]
  }
  if (r <= 0) {
    x = '00'
  } else if (r >= 255) {
      x = 'FF'
    } else {
        let i = Math.floor(r / 16)
        let j = Math.floor(r - i * 16)
        [i, j] = conversion(i, j)
        x = i.toString() + j.toString()
      }
  if (g <= 0) {
    y = '00'
  } else if (g >= 255) {
      y = 'FF'
    } else {
        let i = Math.floor(g / 16)
        let j = Math.floor(g - i * 16)
        [i, j] = conversion(i, j)
        y = i.toString() + j.toString()
      }
  if (b <= 0) {
    z = '00'
  } else if (b >= 255) {
      z = 'FF'
    } else {
        let i = Math.floor(b / 16)
        let j = Math.floor(b - i * 16)
        [i, j] = conversion(i, j)
        z = i.toString() + j.toString()
      }
  return x + y + z
}
于 2020-01-10T02:20:15.180 回答
0

您的代码的唯一问题是您没有声明 j 和 i。在外部函数或内部函数中声明它以使其工作。

function rgb(r, g, b){
  let x
  let y
  let z
  // in outer function 
  let i;
  let j; 


  function conversion(){
    // in lkocal function here 
    // let j ;
    // let i; 

    switch(j) {
            case 10:
              j = 'A'
              break
            case 11:
              j = 'B'
              break
            case 12:
              j = 'C'
              break
            case 13:
              j = 'D'
              break
            case 14:
              j = 'E'
              break
            case 15:
              j = 'F'
          }
          switch(i) {
            case 10:
              i = 'A'
              break
            case 11:
              i = 'B'
              break
            case 12:
              i = 'C'
              break
            case 13:
              i = 'D'
              break
            case 14:
              i = 'E'
              break
            case 15:
              i = 'F'
          }
  }
  if (r <= 0) {
    x = '00'
  } else if (r >= 255) {
      x = 'FF'
    } else {
        let i = Math.floor(r / 16)
        let j = Math.floor(r - i * 16)
        conversion()
        x = i.toString() + j.toString()
      }
  if (g <= 0) {
    y = '00'
  } else if (g >= 255) {
      y = 'FF'
    } else {
        let i = Math.floor(g / 16)
        let j = Math.floor(g - i * 16)
        conversion()
        y = i.toString() + j.toString()
      }
  if (b <= 0) {
    z = '00'
  } else if (b >= 255) {
      z = 'FF'
    } else {
        let i = Math.floor(b / 16)
        let j = Math.floor(b - i * 16)
        conversion()
        z = i.toString() + j.toString()
      }
  return x + y + z
}


var r = rgb(56,67,90);

console.log(r);

于 2020-01-10T02:24:20.067 回答