下面这种怎么封装

像下面这种if elseswitch case怎么做?
要是弄不了,有什么办法可以简化这种那么多if else

var linkHref = window.location.href;

if (linkHref.indexOf('product') != -1 && linkHref.indexOf('products') == -1) {
        
    }else if (linkHref.indexOf('products') != -1){ 
        
    }else if (linkHref.indexOf('video') != -1 && linkHref.indexOf('videos') == -1) {
        
            
    } else if (linkHref.indexOf('tag') != -1) {
    
        
    }  else if (linkHref.indexOf('coupons') != -1) {
        
        
    } else if (linkHref.indexOf('order/list') != -1) {
        
        
    } else if (linkHref.indexOf('order') != -1) {
    
        
    } else if (linkHref.indexOf('web') != -1) {
        
    }
阅读 2.8k
5 个回答
新手上路,请多包涵

这种用switch比较直观吧

不清楚你这个判断中的字符串是在URL的哪个部分,如果是目录或者文件名就可以先取出来存到变量然后用switch,如果是一个参数可能就不好处理了。

function locationIncludes(search){
    return window.location.href.indexOf(search) != -1;
}

switch(true){
  case locationIncludes('product') && ! locationIncludes('products'):

  break;

  case locationIncludes('products'):

  break;

  case locationIncludes('video') && ! locationIncludes('videos'):

  break;

  case locationIncludes('tag'):

  break;

  case locationIncludes('coupons'):

  break;

  case locationIncludes('order/list'):

  break;

  case locationIncludes('order'):

  break;

  case locationIncludes('web'):

  break;
}

这样?

像你这样代码很多重复的地方完全可以封装一个新的方法快速调用的。

String.prototype.contains = function(v){
    return this.indexOf(v) != -1;
}

然后你代码写起来就简单直接了啊

if (linkHref.contains('product') && !linkHref.contains('products')) {
    
}else if (linkHref.contains('products')){ 
    
}

如果你觉得写很多else if不好看的话,我推荐你一种写法

do {
    if(linkHref.contains('product') && !linkHref.contains('products')){
        // ...
        break;
    }
    if(linkHref.contains('products')){
        // ...
        break;
    }
} while(false);

这样写可以通过break来跳出代码块,保证每个if都是互相独立。

一開始多寫點,後面輕鬆點 哈哈哈

// Router
function router(routes) {
    // 所有路由
    this.routes = []
    
    // 預設路由
    this.defaultRoute = routes.default
    // 設定後就拿掉,避免下面重複設定到
    delete routes.default
    
    // 遍歷 object 路由
    for(let pattern in routes) {
        // | 分隔字串
        var patterns = pattern.split('|')
        this.routes.push({
            patterns: patterns, // 需要匹配到的字符串
            handler: routes[pattern] // 對應的方法
        })
    }
}

// 匹配分發路由
router.prototype.dispatch = function(url) {
    // 遍歷所有路由
    for(let i = 0, len = this.routes.length ; i < len ; i++) {
        // 預設匹配到
        let isMatch = true
        const route = this.routes[i]
        
        // 假如有一個不符合就設為 false, 算是逆向思考
        for(let j = 0, len = route.patterns.length; j < len ; j++) {
            if(url.indexOf(route.patterns[j]) === -1) {
                isMatch = false
                break
            }
        }
        // 如果還是 true 代表符合條件,就執行對應的方法並 return
        if(isMatch) {
               return route.handler(route, url)
        }
    }
    // 假設都沒匹配到就會跑到這
    // 如果有設定預設路由的話,就執行
    if(this.defaultRoute) this.defaultRoute(null, url)
}

// 路由設定方式:
// '路由匹配' : 路由匹配後執行的方法
// 路由匹配 : 可輸入字符串,會去匹配網址,如果用|分隔,代表需要同時匹配到分隔
//           的所有字符串
// 路由匹配後執行的方法 : 預設會傳入兩個參數 route, url
// 下面是用 ES6 的箭頭函數,比較好讀,也可以另外寫函數
// 
// var webHandler = function(){...}
// 'web': webHandler 之類的

var myRouter = new router({
    'product|products': (route) => console.log('商品'),
    'products': (route) => console.log('商品2'),
    'video|videos': (route) => console.log('視頻'),
    'tag': (route) => console.log('標籤'),
    'coupons': (route) => console.log('Coupons券'),
    'order/list': (route) => console.log('訂單列表'),
    'order': (route) => console.log('訂單'),
    'web': (route) => console.log('web'),
    default: (route) => console.log('沒匹配到任何路由')
})

var linkHref = "http://test.com/coupons";
myRouter.dispatch(linkHref)
// => Coupons券

var linkHref = "http://test.com/web";
myRouter.dispatch(linkHref)
// => web

實現

jsFiddle

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题