JS 코드를 작성할 때 종종 복잡한 논리적 판단을 접하게 됩니다. 일반적으로 if/else를 사용하거나 여러 조건부 판단을 구현하기 위해 전환할 수 있지만 이는 코드가 증가함에 따라 문제가 발생합니다. 코드의 if/else/switch는 점점 더 비대해지고 이해하기 어려워질 것입니다. 따라서 판단 논리를 보다 우아하게 작성하는 방법을 이 기사에서 시도해 볼 것입니다.
코드를 먼저 보면
/** * 按钮点击事件 * @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 } }复制代码
주의 깊은 학생들도 사례 2와 사례 3이 동일한 논리를 가질 때 약간의 트릭을 발견했습니다. 구문을 실행하고 중단하면 사례 3의 논리가 사례 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 객체의 차이점은 무엇입니까?
문제를 업그레이드해야 합니다. 이전에는 버튼을 클릭할 때만 상태를 판단하면 됐습니다. 이제는 사용자의 신원도 판단해야 합니다.
/** * 按钮点击事件 * @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 객체를 키로 사용:
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)) }复制代码
즉, 배열 루프의 특성을 이용하여 정규 조건에 맞는 로직이 실행되므로, 정규 로직이 존재하기 때문에 공용 로직과 개별 로직을 동시에 실행할 수 있습니다. 규칙에 따라 상상력을 발휘하고 더 많은 플레이 방법을 잠금 해제할 수 있습니다. 이 기사에서는 자세히 설명하지 않습니다.
이 기사에서는 다음을 포함하여 논리적 판단을 작성하는 8가지 방법을 배웠습니다.
이 기사에 관심이 있으시면 작성자의 WeChat 공개 계정을 팔로우하세요: "大 Zhuanzhuanfe"
추천 튜토리얼: "Basic JavaScript Tutorial"
위 내용은 JavaScript로 복잡한 판단을 작성하는 우아한 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!