背景

should.js是一个比拟全的代码测试库,无关框架,引入就可应用,应用起来很不便

应用注意事项和原理浅析

在应用时,引入should.js后,如果你的对象是通过Object.create(null)来创立的,操作如下,该对象.should就不存在

如果是通过失常的创建对象,就能够应用 .should

  • 上面说一下为什么会呈现这样的问题呢?

首先,用Object.create()来创建对象,会把新创建对象的__proto__指向的对象原型设置为传进Object.create中的对象,比方下面的
let obj2 = Object.create(null)
这里就会把obj2的原型对象设置为null,此时obj2就不能继承基类Object的办法和属性,也就不能应用.should了

  • 那么问题来了,为什么依照这种形式let obj2 = Object.create(null)创建对象就不能应用.should了呢?

这里就须要说一下should.js是如何增加到基类Object中的
首先看一下这段代码

其中红框中的代码就是如何把should增加到Object中的,这里是通过应用Object.defineProperty来实现的,这也就是为什么下面第一种形式创立的对象不可能.should了,而第二种形式就能够拿到Object的原型上的should

上面咱们看一下上图中的should$1是怎么来的

当然代码中的一些工具办法也会给到should$1,比方:

这里办法时干什么的就不在这里细说啦,感兴趣的友友们能够自行看下源码哈!
should$1返回了一个Assertion的实例,那么咱们看一下Assertion是什么玩意

Assertion中的办法如下

在上图Assertion返回的办法中,咱们能看到有一个should对象,点开外面还是一个should对象,一层一层嵌套进去,那么它是如何实现should的链式调用的呢?以及它外面的办法时如何增加进去的呢?请看上面这个图:

在这里有一个addChainf的办法,传入须要name和onCall,这里的name就是须要增加的属性,onCall就是这个属性的形容函数,通过这种形式把should中的办法增加进来,放到should的原型上,后续能够通过原型链的形式调用这些办法。这个办法执行后每次都会返回一个this,就是它自身,因而就实现了should的链式调用。

小结

should外面实现了链式调用,咱们上次看的promiz中也实现了链式调用,这两个库实现链式调用还是不一样的,promiz中是在本人的构造函数中返回一个promise属性是本人,而should是通过应用Object.defineProperty的形式间接挂到对象的原型上来实现的,这样做的益处就是基于Object基类的其余类型都能够调用should,比方String、Function、Number等