>  기사  >  웹 프론트엔드  >  JavaScript의 복잡한 논리적 판단을 위한 기술 작성 방법(코드 예제)

JavaScript의 복잡한 논리적 판단을 위한 기술 작성 방법(코드 예제)

不言
不言앞으로
2018-11-23 15:29:383104검색

이 글은 JavaScript의 복잡한 논리적 판단에 대한 기술적인 작성 방법(코드 예제)을 제공합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

JS 코드를 작성할 때 일반적으로 if/else 또는 스위치를 사용하여 여러 조건부 판단을 구현할 수 있지만 이는 논리 복잡성이 증가함에 따라 문제가 발생합니다. 점점 더 부풀어 오르고 이해하기 어려워집니다. 따라서 판단 논리를 보다 우아하게 작성하는 방법을 이 기사에서 시도해 볼 것입니다.

예를 들어

코드를 먼저 보면

/**

 * 按钮点击事件

 * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消

 */
const onButtonClick = (status) => {

  if (status == 1) {

    sendLog('processing') jumpTo('IndexPage')

  } else if (status == 2) {

    sendLog('fail') jumpTo('FailPage')

  } else if (status == 3) {

    sendLog('fail') jumpTo('FailPage')

  } else if (status == 4) {

    sendLog('success') jumpTo('SuccessPage')

  } else if (status == 5) {

    sendLog('cancel') jumpTo('CancelPage')

  } else {

    sendLog('other') jumpTo('Index')

  }

}

코드를 통해 이 버튼의 클릭 로직을 볼 수 있습니다. 다양한 활동 상태에 따라 두 가지 작업을 수행하고, 로그에 묻힌 포인트를 보내고 해당 페이지로 이동합니다. . 이 코드에 대한 재작성 계획을 쉽게 제시할 수 있으며 스위치가 나타납니다.

/**
 * 按钮点击事件
 * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
 */
const onButtonClick = (status) => {
  switch (status) {

    case 1:

      sendLog('processing')

      jumpTo('IndexPage')

      break

    case 2:

    case 3:

      sendLog('fail')

      jumpTo('FailPage')

      break

    case 4:

      sendLog('success')

      jumpTo('SuccessPage')

      break

    case 5:

      sendLog('cancel')

      jumpTo('CancelPage')

      break

    default:

      sendLog('other')

      jumpTo('Index')

      break

  }

}

글쎄, 이것은 if/else보다 훨씬 명확해 보입니다. 신중한 학생들도 사례 2와 사례 3이 동일한 논리를 가질 때 발견했습니다. , 그들은 문장을 실행하고 중단하기 위해 Case 3의 논리가 Case 2에서 자동으로 실행될 수 있습니다.

이때 어떤 학생들은 더 간단하게 작성하는 방법이 있다고 말할 것입니다.

const actions = {

  '1': ['processing', 'IndexPage'],

  '2': ['fail', 'FailPage'],

  '3': ['fail', 'FailPage'],

  '4': ['success', 'SuccessPage'],

  '5': ['cancel', 'CancelPage'],

  'default': ['other', 'Index'],

}

/**

 * 按钮点击事件

 * @param {number} status 活动状态:1开团进行中 2开团失败 3 商品售罄 4 开团成功 5 系统取消

 */

const onButtonClick = (status) => {

  let action = actions[status] || actions['default'],

    logName = action[0],

    pageName = action[1]

  sendLog(logName)

  jumpTo(pageName)

}

위 코드가 더 깔끔해 보입니다. 이 방법의 영리함은 판단 조건을 객체의 속성 이름으로 사용하고, 처리 로직 버튼을 클릭하면 객체의 속성을 검색하여 객체의 속성 값을 논리적으로 판단합니다. 이 작성 방법은 특히 단항 조건 판단에 적합합니다.

다른 방법으로 쓰는 방법은 없나요? 일부:

const actions = new Map([

  [1, ['processing', 'IndexPage']],

  [2, ['fail', 'FailPage']],

  [3, ['fail', 'FailPage']],

  [4, ['success', 'SuccessPage']],

  [5, ['cancel', 'CancelPage']],

  ['default', ['other', 'Index']]

])

/**

 * 按钮点击事件

 * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消

 */

const onButtonClick = (status) => {

  let action = actions.get(status) || actions.get('default')

  sendLog(action[0])

  jumpTo(action[1])

}

이렇게 작성하면 es6의 Map 객체를 사용하는 것이 더 재미있지 않나요? Map 객체와 Object 객체의 차이점은 무엇입니까?

1. 객체에는 일반적으로 자체 프로토타입이 있으므로 객체에는 항상 "프로토타입" 키가 있습니다.

2. 객체의 키는 문자열이나 기호만 될 수 있지만 맵의 키는 어떤 값이라도 될 수 있습니다.

3. 맵의 키-값 쌍 수는 크기 속성을 통해 쉽게 얻을 수 있지만 객체의 키-값 쌍 수는 수동으로만 확인할 수 있습니다.

문제를 업그레이드해야 합니다. 과거에는 버튼을 클릭할 때만 상태를 판단하면 되었습니다. 이제는 사용자의 신원도 판단해야 합니다.

/**

 * 按钮点击事件

 * @param {number} status 活动状态:1开团进行中 2开团失败 3 开团成功 4 商品售罄 5 有库存未开团

 * @param {string} identity 身份标识:guest客态 master主态

 */

const onButtonClick = (status, identity) => {

  if (identity == 'guest') {

    if (status == 1) {

      //do sth

    } else if (status == 2) {

      //do sth

    } else if (status == 3) {

      //do sth

    } else if (status == 4) {

      //do sth

    } else if (status == 5) {

      //do sth

    } else {

      //do sth

    }

  } else if (identity == 'master') {

    if (status == 1) {

      //do sth

    } else if (status == 2) {

      //do sth

    } else if (status == 3) {

      //do sth

    } else if (status == 4) {

      //do sth

    } else if (status == 5) {

      //do sth

    } else {

      //do sth

    }

  }

}

각 판단의 구체적인 논리를 작성하지 않은 점 양해해 주세요. 코드가 너무 길기 때문이죠.

다시 if/else를 사용해서 죄송합니다. 왜냐하면 많은 사람들이 아직도 그렇게 긴 논리적 판단을 작성하기 위해 if/else를 사용하고 있기 때문입니다.

위의 예를 보면 논리가 이진 판단으로 업그레이드되면 판단량이 두 배가 되고, 코드 양도 두 배로 늘어난다는 것을 알 수 있습니다. 이때 어떻게 하면 좀 더 산뜻하게 작성할 수 있을까요?

const actions = new Map([

  ['guest_1', () => { /*do sth*/ }],

  ['guest_2', () => { /*do sth*/ }],

  ['guest_3', () => { /*do sth*/ }],

  ['guest_4', () => { /*do sth*/ }],

  ['guest_5', () => { /*do sth*/ }],

  ['master_1', () => { /*do sth*/ }],

  ['master_2', () => { /*do sth*/ }],

  ['master_3', () => { /*do sth*/ }],

  ['master_4', () => { /*do sth*/ }],

  ['master_5', () => { /*do sth*/ }],

  ['default', () => { /*do sth*/ }],

])



/**

 * 按钮点击事件

 * @param {string} identity 身份标识:guest客态 master主态

 * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 开团成功 4 商品售罄 5 有库存未开团

 */

const onButtonClick = (identity, status) => {

  let action = actions.get(`${identity}_${status}`) || actions.get('default')

  action.call(this)

}

위 코드의 핵심 로직은 두 조건을 문자열로 연결하고, 조건 문자열을 키로, 처리 함수를 값으로 사용하여 Map 객체를 검색하고 실행하는 것입니다. 이 작성 방법은 특히 판단할 때 사용됩니다. 여러 조건을 사용하기 쉽습니다.

물론, 위의 코드를 Object 객체를 이용하여 구현한다면 비슷할 것입니다.

const actions = {

  'guest_1': () => { /*do sth*/ },

  'guest_2': () => { /*do sth*/ },

  //....

}



const onButtonClick = (identity, status) => {

  let action = actions[`${identity}_${status}`] || actions['default']

  action.call(this)

}

如果有些同学觉得把查询条件拼成字符串有点别扭,那还有一种方案,就是用Map对象,以Object对象作为key:

const actions = new Map([

  [{

    identity: 'guest',

    status: 1

  }, () => { /*do sth*/ }],

  [{

    identity: 'guest',

    status: 2

  }, () => { /*do sth*/ }],

  //...

])



const onButtonClick = (identity, status) => {

  let action = [...actions].filter(([key, value]) => (key.identity == identity && key.status == status))

  action.forEach(([key, value]) => value.call(this))

}

조금 더 발전된 것이 아닐까요?

지도와 객체의 차이점은 여기서도 확인할 수 있습니다. 지도는 모든 유형의 데이터를 키로 사용할 수 있습니다.

이제 난이도를 조금 업그레이드해 보겠습니다. 게스트의 경우 상태1-4의 처리 논리가 동일하면 어떻게 될까요? 최악의 경우는 다음과 같습니다.

const actions = new Map([

  [{

    identity: 'guest',

    status: 1

  }, () => { /* functionA */ }],

  [{

    identity: 'guest',

    status: 2

  }, () => { /* functionA */ }],

  [{

    identity: 'guest',

    status: 3

  }, () => { /* functionA */ }],

  [{

    identity: 'guest',

    status: 4

  }, () => { /* functionA */ }],

  [{

    identity: 'guest',

    status: 5

  }, () => { /* functionB */ }],

  //...

])

처리 논리 함수를 캐시하는 것이 더 좋습니다. :

const actions = () => {

  const functionA = () => { /*do sth*/ }

  const functionB = () => { /*do sth*/ }

  return new Map([

    [{

      identity: 'guest',

      status: 1

    }, functionA],

    [{

      identity: 'guest',

      status: 2

    }, functionA],

    [{

      identity: 'guest',

      status: 3

    }, functionA],

    [{

      identity: 'guest',

      status: 4

    }, functionA],

    [{

      identity: 'guest',

      status: 5

    }, functionB],

    //...

  ])

}



const onButtonClick = (identity, status) => {

  let action = [...actions()].filter(([key, value]) => (key.identity == identity && key.status == status))

  action.forEach(([key, value]) => value.call(this))

}

이렇게 작성하면 이미 일상적인 요구 사항을 충족할 수 있지만, 엄밀히 말하면 functionA를 4번 다시 작성하는 것은 여전히 ​​조금 불편합니다. 예를 들어 ID에는 3개의 상태가 있고 상태에는 10개의 상태가 있습니다. , 그러면 30개의 처리 논리를 정의해야 하며 이러한 논리 중 상당수가 동일한 경우가 많습니다. 이는 작성자가 받아들이고 싶지 않은 것 같습니다.

const actions = () => {

  const functionA = () => { /*do sth*/ }

  const functionB = () => { /*do sth*/ }

  return new Map([

    [/^guest_[1-4]$/, functionA],

    [/^guest_5$/, functionB],

    //...

  ])

}



const onButtonClick = (identity, status) => {

  let action = [...actions()].filter(([key, value]) => (key.test(`${identity}_${status}`)))

  action.forEach(([key, value]) => value.call(this))

}

의 장점은 다음과 같습니다. 여기서는 맵이 더 눈에 띄고, 일반형도 키로 사용할 수 있기 때문에 가능성은 무궁무진합니다. 수요가 생기면 모든 손님 상황에 대해 로그 매장지를 보내야 하고, 상태가 다른 경우에도 별도의 논리적 처리가 필요하기 때문이죠.

const actions = () => {

  const functionA = () => { /*do sth*/ }

  const functionB = () => { /*do sth*/ }

  const functionC = () => { /*send log*/ }

  return new Map([

    [/^guest_[1-4]$/, functionA],

    [/^guest_5$/, functionB],

    [/^guest_.*$/, functionC],

    //...

  ])

}



const onButtonClick = (identity, status) => {

  let action = [...actions()].filter(([key, value]) => (key.test(`${identity}_${status}`)))

  action.forEach(([key, value]) => value.call(this))

}

즉, 배열 루프의 특성을 이용하여 정규 조건에 맞는 로직이 실행되므로, 정규 로직이 존재하기 때문에 공용 로직과 개별 로직을 동시에 실행할 수 있습니다. 규칙에 따라 상상력을 발휘하고 더 많은 플레이 방법을 잠금 해제할 수 있습니다. 이 기사에서는 자세히 설명하지 않습니다.

Summary

이 기사에서는 다음을 포함하여 논리적 판단을 작성하는 8가지 방법을 배웠습니다.

  • if/else

  • switch

  • 단방향 판단을 내릴 때: Object에 저장

  • 단방향 판단 시기: 지도에 저장

  • 다중 판단 시: 조건을 문자열로 연결하여 Object에 저장

  • 다중 판단 시: 조건을 문자열로 연결하여 저장 it in the Map

  • 다중 판단시 : 조건을 맵에 Object로 저장

  • 다중 판단시 : 일반 글쓰기로 조건을 맵에 저장

이때, 이 기사도 끝이 나기를 바랍니다. 여러분의 미래에는 if/else/switch만 사용하지 않기를 바랍니다.

위 내용은 JavaScript의 복잡한 논리적 판단을 위한 기술 작성 방법(코드 예제)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제