共计 1189 个字符,预计需要花费 3 分钟才能阅读完成。
背景
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 等