前端中的Robust

要想代码强壮,容错是不可少的。开发中要考虑各种情况, 容错代码包括数据处理业务

这里主说数据处理

数据处理

取值赋值(null-safe)

现状:

if (obj != null) iWant = obj.value;
const val = obj.list.item.string

可能报错TypeError: Cannot read property 'val' of undefined

开发中如此解决:

if(obj&&obj.list&&obj.list.item){
  const val = obj.list.item.string
}

解决方案:

  • 写法上优化
(((a.b || {}).c || {}).d || {}).e
  • reduce方案
const get = (path, o) => path.reduce((prev, cur)=> (prev && prev[cur]) ? prev[cur]:null , o);

//use
get(['list','item','string'], obj)

以上方法可以curry化,更方便,path总不能每次都写一次吧

const get = path => obj => path.reduce((prev, cur)=> (prev && prev[cur]) ? prev[cur]:null , o);

const getStr = get(['list','item','string']);

//固化参数,会方便很多
getStr(obj1)
getStr(obj2)
const get = (prop, ...props) => obj => obj == null || prop == null ? obj : get(...props)(obj[prop]);
  • try catch

try { b = a.b.c.d.e } catch(e) {}

const tryCatch = f => try{
  return Right(f())
}catch(e){
  return Left(e) || defaultValue
}


function deepGet (obj, properties, defaultValue) {
    if (obj === undefined || obj === null) {
        return defaultValue;
    }
    if (properties.length === 0) {
        return obj;
    }
    var foundSoFar = obj[properties[0]];
    var remainingProperties = properties.slice(1);
    return deepGet(foundSoFar, remainingProperties, defaultValue);
}
//使用
deepGet(obj, ['a','c','d','e'], {});


//稳定版
function _try(func, fallbackValue) {
    try {
        var value = func();
        return (value === null || value === undefined) ? fallbackValue : value;
    } catch (e) {
        return fallbackValue;
    }
}
//使用
_try(() => user.address.postcode)
_try(() => user.address.postcode,'none');
  • defineProperty版
Object.defineProperty(Object.prototype, 'safeGet', { 
    enumerable: false,
    writable: false,
    value: function(p) {
        return p.split('.').reduce((acc, k) => {
            if (acc && k in acc) return acc[k];
            return undefined;
        }, this);
    }
});
//使用
obj.safeGet('a.c.d.e')
  • ES6的proxy
const isObject = obj => obj && typeof obj === 'object';
const hasKey = (obj, key) => key in obj;
const Undefined = new Proxy({}, {
  get: function(target, name){
      return Undefined;
  }
});
const either = (val,fallback) => (val === Undefined? fallback : val);

//代理
function safe (obj) {
  return new Proxy(obj, {
    get: function(target, name){
      return hasKey(target, name)
        ? isObject(target[name])
            ? safe(target[name])
            : target[name]
        : Undefined;
    }
  });
}
//使用
const mySafeObj = safe({
  a : 'www',
  d : {
    name : 'd'
  }
});
console.log(mySafeObj.d.e);

console.log(either(mySafeObj.f.e.name, false)); 

取值赋值之外

继取值赋值之后的容错,大概就剩下拿到数据然后处理了吧切记,取到undefined或者null 不要随意给其处理函数比如null.reduce,多担心这种问题 就多做做容错吧,不行到话 直接写try catch

对接

对接这里就不谈了,根据前后端约定,做全局ajax处理吧,去他么的业务.

上次更新: 12/2/2018, 4:45:00 PM