前端中的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)
- lodash的get
- 递归
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处理吧,去他么的业务.