這些優(yōu)化技巧可以避免我們?cè)?JS 中過(guò)多的使用 IF 語(yǔ)句
最近在重構(gòu)代碼時(shí),我發(fā)現(xiàn)早期的代碼使用太多的 if 語(yǔ)句,其程度是我從未見(jiàn)過(guò)的。這就是為什么我認(rèn)為分享這些簡(jiǎn)單的技巧是非常重要的,這些技巧可以幫助我們避免過(guò)多的使用 if 語(yǔ)句。
接下來(lái)會(huì)介紹6種方式來(lái)代替 if 的使用,這樣做不是堅(jiān)決不使用 if 偏執(zhí)狂,而是換個(gè)方式思考我們的編碼思路。
1. 三元運(yùn)算符
(1) 事例1
帶有IF的代碼:
- function saveCustomer(customer) {
- if (isCustomerValid(customer)) {
- database.save(customer)
- } else {
- alert('customer is invalid')
- }
- }
重構(gòu)后代碼:
- function saveCustomer(customer) {
- return isCustomerValid(customer)
- ? database.save(customer)
- : alert('customer is invalid')
- }
使用 ES6
- const saveCustomer = customer =>
- isCustomerValid(customer)?
- database.save(customer) : alert('customer is invalid')
(2) 事例2
帶有IF的代碼:
- function customerValidation(customer) {
- if (!customer.email) {
- return error('email is require')
- } else if (!customer.login) {
- return error('login is required')
- } else if (!customer.name) {
- return error('name is required')
- } else {
- return customer
- }
- }
重構(gòu)后代碼:
- const customercustomerValidation = customer =>
- !customer.email ? error('email is required')
- : !customer.login ? error('login is required')
- : !customer.name ? error('name is required')
- : customer
(3) 事例3
帶有IF的代碼:
- function getEventTarget(evt) {
- if (!evt) {
- evt = window.event;
- }
- if (!evt) {
- return;
- }
- const target;
- if (evt.target) {
- target = evt.target;
- } else {
- target = evt.srcElement;
- }
- return target;
- }
重構(gòu)后代碼:
- function getEventTarget(evt) {
- evtevt = evt || window.event;
- return evt && (evt.target || evt.srcElement);
- }
2. 短路運(yùn)算符
(1) 事例1
帶有IF的代碼:
- const isOnline = true;
- const makeReservation= ()=>{};
- const user = {
- name:'Damian',
- age:32,
- dni:33295000
- };
- if (isOnline){
- makeReservation(user);
- }
重構(gòu)后代碼:
- const isOnline = true;
- const makeReservation= ()=>{};
- const user = {
- name:'Damian',
- age:32,
- dni:33295000
- };
- isOnline&&makeReservation(user);
(2) 事例2
帶有IF的代碼:
- const active = true;
- const loan = {
- uuid:123456,
- ammount:10,
- requestedBy:'rick'
- };
- const sendMoney = ()=>{};
- if (active&&loan){
- sendMoney();
- }
重構(gòu)后代碼:
- const active = true;
- const loan = {
- uuid:123456,
- ammount:10,
- requestedBy:'rick'
- };
- const sendMoney = ()=>{};
- ctive && loan && sendMoney();
3. 函數(shù)委托
事例1
帶有IF的代碼:
- function itemDropped(item, location) {
- if (!item) {
- return false;
- } else if (outOfBounds(location) {
- var error = outOfBounds;
- server.notify(item, error);
- items.resetAll();
- return false;
- } else {
- animateCanvas();
- server.notify(item, location);
- return true;
- }
重構(gòu)后代碼:
- function itemDropped(item, location) {
- const dropOut = function() {
- server.notify(item, outOfBounds);
- items.resetAll();
- return false;
- }
- const dropIn = function() {
- server.notify(item, location);
- animateCanvas();
- return true;
- }
- return !!item && (outOfBounds(location) ? dropOut() : dropIn());
- }
4. 非分支策略
此技巧嘗試避免使用switch語(yǔ)句,相反是用鍵/值創(chuàng)建一個(gè)映射并使用一個(gè)函數(shù)訪(fǎng)問(wèn)作為參數(shù)傳遞的鍵的值。
(1) 事例1
帶有switch的代碼:
- switch(breed){
- case 'border':
- return 'Border Collies are good boys and girls.';
- break;
- case 'pitbull':
- return 'Pit Bulls are good boys and girls.';
- break;
- case 'german':
- return 'German Shepherds are good boys and girls.';
- break;
- default:
- return 'Im default'
- }
重構(gòu)后代碼:
- const dogSwitch = (breed) =>({
- "border": "Border Collies are good boys and girls.",
- "pitbull": "Pit Bulls are good boys and girls.",
- "german": "German Shepherds are good boys and girls.",
- })[breed]||'Im the default';
- dogSwitch("border xxx")
5. 作為數(shù)據(jù)的函數(shù)
我們知道在JS中函數(shù)是第一個(gè)類(lèi),所以使用它我們可以把代碼分割成一個(gè)函數(shù)對(duì)象。
帶有IF的代碼:
- const calc = {
- run: function(op, n1, n2) {
- const result;
- if (op == "add") {
- result = n1 + n2;
- } else if (op == "sub" ) {
- result = n1 - n2;
- } else if (op == "mult" ) {
- result = n1 * n2;
- } else if (op == "div" ) {
- result = n1 / n2;
- }
- return result;
- }
- }
- calc.run("sub", 5, 3); //2
重構(gòu)后代碼:
- const calc = {
- add : function(a,b) {
- return a + b;
- },
- sub : function(a,b) {
- return a - b;
- },
- mult : function(a,b) {
- return a * b;
- },
- div : function(a,b) {
- return a / b;
- },
- run: function(fn, a, b) {
- return fn && fn(a,b);
- }
- }
- calc.run(calc.mult, 7, 4); //28
6. 多態(tài)性
多態(tài)性是對(duì)象具有多種形式的能力。OOP中多態(tài)性最常見(jiàn)的用法是使用父類(lèi)引用來(lái)引用子類(lèi)對(duì)象。
帶有IF的代碼:
- const bob = {
- name:'Bob',
- salary:1000,
- job_type:'DEVELOPER'
- };
- const mary = {
- name:'Mary',
- salary:1000,
- job_type:'QA'
- };
- const calc = (person) =>{
- if (people.job_type==='DEVELOPER')
- return person.salary+9000*0.10;
- if (people.job_type==='QA')
- return person.salary+1000*0.60;
- }
- console.log('Salary',calc(bob));
- console.log('Salary',calc(mary));
重構(gòu)后代碼:
- const qaSalary = (base) => base+9000*0.10;
- const devSalary = (base) => base+1000*0.60;
- //Add function to the object.
- const bob = {
- name:'Bob',
- salary:1000,
- job_type:'DEVELOPER',
- calc: devSalary
- };
- const mary = {
- name:'Mary',
- salary:1000,
- job_type:'QA',
- calc: qaSalary
- };
- console.log('Salary',bob.calc(bob.salary));
- console.log('Salary',mary.calc(mary.salary));