数据字段防卫探索

数据字段防卫探索

这个标题不知道怎么取,估计没人看得懂,还是直接看背景吧 -_-!!

背景

某天,小Y借到一个需求:页面这里要展示一个列表,cgi数据字段是xxxlist

太简单了,几分钟的事情:

DB.getData({
    // ...
    succ: function(data) {
        for (var i = 0, l = data.result.xxxlist.length; i < l; ++i) {
            showItem(data.result.xxxlist[i]);
        }
    }
});

自测,免测发布,完美!

但是,没过多久,客服接到一堆的用户投诉,xxx页面打开白屏!

小Y吓了一跳,怎么可能,刚刚那个代码那么简单,绝对不会出错的!

用用户投诉的页面,打开控制台一看:

发现报了一个错:

排查之后发现,原因是data.result.xxxlistundefined

顿时一万匹草泥马在心里奔腾而过,不是说好是个列表吗,没有列表应该返回[]

没办法,小Y只能紧急修复代码:

DB.getData({
    // ...
    succ: function(data) {
        if (data && data.result && data.result.xxxlist) {
            for (var i = 0, l = data.result.xxxlist.length; i < l; ++i) {
                showItem(data.result.xxxlist[i]);
            }
        }
    }
});

分析

上面的背景案例中,小Y忽略了一个很重要的原则:

永远不要相信输入!

还记得老师曾经这样教导我们:

在编写函数的时候,一定要检测参数是否合理

对于前端来说,cgi数据也是一样的,永远不能相信cgi传过来的数据

有人会说,这只是小Y不够严谨,当需要用某些字段的时候,就应该先检测

那就又疏忽了,人也是不可信的,当bugfix很紧急的时候还记得吗?别人写的代码能控制吗?再细心的人也会有疏忽的时候

另外,如果都加上防卫代码的时候,代码可能会长成这样:

DB.getData({
    // ...
    succ: function(data) {
        if (!data) return;
        if (!data.a) return;
        if (data.b) {
            // ...
        }

        if (data.c) {
            // ...
        }

        if (data.d && data.d.e) {
            // ...
        }

        // 你就一直if下去吧,我不拦你!

    }
});

通过背景案例以及分析,现在终于可以解释数据字段防卫是什么东东了

在访问object.key时,防止object可能是undefined或者null时抛错

方案

对于这个问题,这里抛几个方案,希望可以引出各位读者的玉!

方案一:抽象cgi数据

类似orm那样,预先定义model(cgi数据)的schema,如果定义了schema,那我们就可以添加默认值机制

这个方案的本质就是对cgi数据添加了一层加工层,让cgi数据变得可信

优点:抽象cgi数据不仅可以做数据字段防卫,还可以做很多事情 缺点:太重,毫无疑问的

方案二:重定义undefined

比如我们可以这样:

window.undefined = { length: 0 };

优点:简单 缺点:某些浏览器不支持,见下图;typeof 会出问题

在浏览器不支持的情况下,这个方案可以被枪毙了 -_-!!

方案三:封装获取数据字段的接口

获取数据字段不是原生的object.key,而是util.get(object, key),在get方法里面进行防卫处理

优点:实现统一简单 缺点:改变了原来的编程习惯;原有代码需要改动

方案四:让工具帮你

让工具透明的解决这个问题,直接看例子吧

function test(obj) {
    var T;
    T = require('tools');
    var name = T.cookie.get('name');
    if (!obj) {
        obj = {
            count: {
                count: 5
            }
        };
    }
    obj.count.count = 6;
}

经过工具之后:

function test(obj) {
    var T;
    T = require('tools');
    T.cookie= T.cookie|| T.cookie=== '' ? T.cookie: {};
    var name = T.cookie.get('name');
    if (!obj) {
        obj = { count: { count: 5 } };
    }
    obj.count = obj.count || obj.count === '' ? obj.count : {};
    obj.count.count = 6;
}

通过工具保证,在访问object.key之前,object不会是undefined或者是null

优点:透明 缺点:依赖工具的智能与强大;会添加一些多余代码(因为工具无法识别哪些变量才是真正需要的)

感兴趣的话可以看下作者编写的工具data-member-defender

该工具还需要完善,欢迎提 issue !

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI研习社

犹他州空气质量分析-从EPA的空气质量服务站API中抓取数据

住在山谷里有点像生活在汤碗里,所有重物似乎都集中在碗底。 我想说犹他州的许多山谷被称为地垒和地堑,虽然我确信一些地质学家可能纠正我的错误。无论如何,四面环山意味...

672
来自专栏web前端教室

继续电商网站的购物车

这一阶段的内容会比较枯燥,没办法啊。纯业务逻辑这块,写不出情趣来。有兴趣的就耐着性子看看,没耐性的可以等等看,改天写个有趣的内容之类的 我这个简单的购物车从功能...

1717
来自专栏JackieZheng

AngularJS入门心得1——directive和controller如何通信

  粗略地翻了一遍《JavaScript DOM编程艺术》,就以为可以接过AngularJS的一招半式,一个星期过去了,我发现自己还是Too Young,Too...

1966
来自专栏Albert陈凯

2018-08-25 2000万条数据迁移从几天到几个小时

一直不知道性能优化都要做些什么,从哪方面思考,直到最近接手了一个公司的小项目,可谓麻雀虽小五脏俱全。让我这个编程小白学到了很多性能优化的知识,或者说一些思考方式...

732
来自专栏Java架构

2018年Java程序员最新BAT面试题

2386
来自专栏java达人

为什么又要造一个叫 Latke 的轮子

欢迎投稿 黑客派作品 框架 使用框架的好处很多,它规范了我们的开发方式,减少了出错的可能性,让我们可以更快地完成开发目标,后续维护也可以有章可循;使用框架的弊...

1775
来自专栏ImportSource

设计模式-搞个接口,留有余地,让你我不再尴尬

设计模式,Design Patterns,Pattern,翻译为“模式”总感觉不够接地气,用今天的话来说可以叫“套路”。设计模式就是写代码的过程中一些常规打法和...

33811
来自专栏NetCore

复杂而艰辛的重构之路--起步

你有没有试过,当你踏入一个新的公司,看到了几千几万几十万代码的时候,那种崩溃的感觉? 代码多不可怕,怕的是代码的可读性、维护性、扩展性是如此之差,这时候该怎么办...

1829
来自专栏web前端教室

浅浅的聊一下React

image.png 要写一个组件,当然是从需求开始设计它。但要组件的边界,就是这个组件,它的最多能做什么?一个通用的组件,它也是有倾向性的,不可能适合完全所有的...

2009
来自专栏程序员的SOD蜜

使用ORM框架,必须迁就数据库的设计吗?

我在CSDN发表了一个帖子,发布一款强大的ORM工具--PDF.NET集成开发工具 ,有个朋友caozhy提出了非常尖锐的问题,我对他的问题做了回答,现在觉得他...

2659

扫码关注云+社区