前言
使用should.js断言库的时候,我们并未对被测试方法进行任何处理,却以调用属性的方式调用should,这是如何实现的呢?
揭秘
于是乎我们打开should.js的源码,发现类库会默认执行以下代码:
Object.defineProperty(Object.prototype, 'should', {
set: function(){},
get: function(){
return should(this);
},
configurable: true
});
shouldjs为Object对象添加了should属性,定义成无法赋值,返回用should方法处理后的对象(should.Assertion)。
探索
should.js是一款BDD风格的断言库,用起来能感受到在书写自然语言,如果觉得英文没有那么贴切的化,我们甚至可以用中文来书写。
例如断句:
'123'.should.equal('123').and.be.a.String()
用中文书写:
'123'.应该.等于('123').且.是.个.字符串()
是不是很有趣,我们要怎么实现呢?只需要添加以下代码:
// 扩展should别名
shoud.extend('应该', Object.prototype)
// 扩展属性别名
['是', '个', '且'].forEach(function(name) {
Assertion.addChain(name);
});
// 扩展方法别名
Assertion.alias('equal', '等于');
Assertion.alias('String', '字符串');
shouldjs使用了js设计模式的链式调用模式,此模式除了让调用过程更接近自然语言,还可以减少代码量。
扩展
我们经常要写这种代码:
if (room && room.desks && room.desks.length > 10)
console.log('这是一个大教室');
有没有优美的写法呢?
if (room?.desks?.length > 10)
console.log('这是一个大教室');
这是一种链式调用的写法,?.符号判断左边是否为null或undefined。
?.符号还只是个提案,想要尝试的话,可以通过babel加上syntax-optional-chaining插件编译运行。