最近在重构代码时,我发现早期的代码使用太多的 if 语句,其程度是我从未见过的。这就是为什么我认为分享这些简单的技巧是非常重要的,这些技巧可以帮助我们避免过多的使用 if 语句。
接下来会介绍6种方式来代替 if 的使用,这样做不是坚决不使用 if 偏执狂,而是换个方式思考我们的编码思路。
1. 三元运算符
(1) 事例1
带有IF的代码:
- function saveCustomer(customer) {
- if (isCustomerValid(customer)) {
- database.save(customer)
- } else {
- alert('customer is invalid')
- }
- }
重构后代码:
- 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
- }
- }
重构后代码:
- 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;
- }
重构后代码:
- function getEventTarget(evt) {
- evtevt = evt || window.event;
- return evt && (evt.target || evt.srcElement);
- }
2. 短路运算符
(1) 事例1
带有IF的代码:
- const isOnline = true;
- const makeReservation= ()=>{};
- const user = {
- name:'Damian',
- age:32,
- dni:33295000
- };
- if (isOnline){
- makeReservation(user);
- }
重构后代码:
- 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();
- }
重构后代码:
- const active = true;
- const loan = {
- uuid:123456,
- ammount:10,
- requestedBy:'rick'
- };
- const sendMoney = ()=>{};
- ctive && loan && sendMoney();
3. 函数委托
事例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;
- }
重构后代码:
- 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语句,相反是用键/值创建一个映射并使用一个函数访问作为参数传递的键的值。
(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'
- }
重构后代码:
- 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. 作为数据的函数
我们知道在JS中函数是第一个类,所以使用它我们可以把代码分割成一个函数对象。
带有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
重构后代码:
- 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. 多态性
多态性是对象具有多种形式的能力。OOP中多态性最常见的用法是使用父类引用来引用子类对象。
带有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));
重构后代码:
- 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));