should.js 写法实现

关于 should.js

先上代码

1
2
3
4
5
6
7
8
var should = require('should');

var user = {
name: 'tj',
pets: ['tobi', 'loki', 'jane', 'bandit']
};

user.should.have.property('name', 'tj'); // true

看到这样的写法是不是很酷炫,反正我当时就是,我们来一步一步实现它。

原型链

首先user这个对象本身是没有should这个属性的,那就肯定是往原型链上找了,所以事先把这个属性挂载到Object.prototype上

1
2
3
4
5
6
7
8
9
10
11
// 1、
function tool(obj){
this._obj = obj;
}

// 2、
Object.defineProperty(Object.prototype,'tool',{
get: function(){
return new tool(this);
}
});
  • 1、先定义一个函数,将调用对象的this当做tool函数的内部对象传入
  • 2、在Object.prototype上定义一个名为为tool的属性,设置这个属性的get访问拦截返回通过构造函数实例化的tool

看看效果

1
2
3
4
5
6
7
8
9

const tool = require('./lib/defind');

const user = {
a: 1,
b: 'test'
};

console.log(user.tool); // 3、

  • 3、打印了 tool { _obj: { a: 1, b: 'test' } }

就是这么简单实现了这种酷炫的写法,添加一个tool的方法判断调用对象是否有该属性

1
2
3
tool.prototype.has = function(key){
return this._obj.hasOwnProperty(key);
}

  • 4、刚才在tool函数里保存的_obj现在起作用了

console一下

1
2
3
4
let has = user.tool.has('a');
console.log(has); // true
has = user.tool.has('c');
console.log(has); // false

剩下的api有兴趣的朋友自己实现吧~

参考链接: