think 对象

框架中内置 think 全局对象,方便在项目中随时随地使用。

API

think.app

think.app 为 Koa Application 对象的实例,系统启动时生成。

此外为 app 扩展了更多的属性。

  • think.app.think 等同于 think 对象,方便有些地方传入了 app 对象,同时要使用 think 对象上的其他方法
  • think.app.modules 模块列表,单模块项目下为空数组
  • think.app.controllers 存放项目下的 controller 文件,便于后续快速调用
  • think.app.logics 存放项目下的 logic 文件
  • think.app.models 存放项目下的模型文件
  • think.app.services 存放 service 文件
  • think.app.routers 存放自定义路由配置
  • think.app.validators 存放校验配置
  • think.app.server 创建 HTTP 服务后的 server 对象
    如果想要查下这些属性具体的值,可以在 appReady 事件中进行。
  1. think.app.on('appReady', () => {
  2. console.log(think.app.controllers)
  3. })

think.ROOT_PATH

项目的根目录,其他目录可以通过该目录来生成,如:

  1. const runtimePath = path.join(think.ROOT_PATH, 'runtime/');
  2. const viewPath = path.join(think.ROOT_PATH, 'view/');

think.APP_PATH

APP 根目录,默认为 ${think.ROOT_PATH}/app,如果项目不需要转译的话,那么默认路径为:${think.ROOT_PATH}/src

think.env

当前运行环境,等同于 think.app.env,值在 development.js 之类的入口文件中定义。

think.version

当前 ThinkJS 的版本号。

think.config(name, value, m)

  • name {String} 配置名
  • value {Mixed} 配置值
  • m {String} 模块名,多模块项目下使用
    读取或者设置配置,该功能由 think-config 模块实现。在 context、controller、logic 上可以直接通过 this.config 方法来操作配置。
  1. // 获取配置
  2. const value1 = think.config('name');
  3. // 指定模块获取配置,多模块项目下有效
  4. const value2 = think.config('name', undefined, 'admin');
  5. // 设置配置
  6. think.config('name', 'value');
  7. // 指定模块设置配置值
  8. think.config('name', 'value', 'admin');

think.Controller

控制器基类,其他控制器类继承该类。

  1. // src/controller/user.js
  2. module.exports = class userController extends think.Controller {
  3. indexAction() {
  4. }
  5. }

think.Logic

Logic 基类,继承自 think.Controller

  1. // src/logic/user.js
  2. module.exports = class userLogic extends think.Logic {
  3. indexAction() {
  4. }
  5. }

think.Service

Service 基类,其他 Service 类继承该类。

  1. // src/service/sms.js
  2. module.exports = class extends think.Service {
  3. }

think.service(name, m, …args)

  • name {String} Service 名称
  • m {String} 模块名,多模块项目下有效
  • …args {Array} 实例化 Service 类需要的参数。单模块项目下,会把 m 参数补充导 args 里。
    实例化 Service 类,如果导出的对象不是个类,那么直接返回。
  1. const instance1 = think.service('sms');
  2. const instance2 = think.service('sms', 'admin');

think.beforeStartServer(fn)

  • fn {Function} 要注册的函数名
    服务启动之前要注册执行的函数,如果有异步操作,fn 需要返回 Promise。

think.isArray(array)

  • array {any} 判断输入是否是数组
  • return {Boolean}
    判断是否是数组,等同于 Array.isArray
  1. think.isArray([]); // true
  2. think.isArray({}); // false

think.isBoolean(boolean)

  • boolean {any}
    判断输入是否是布尔值
  1. think.isBoolean(false); // true

think.isInt(any)

  • any {any}
    判断输入的是否是整数

think.isNull(any)

  • any {any}
    判断输入是 null,也可以直接通过 xxx === null 来判断。

think.isNullOrUndefined(any)

  • any {any}
    判断输入是 null 或者 undefined

think.isNumber(number)

  • number {any}
    判断输入是否是数字
  1. think.isNumber(1); // true

think.isString(str)

  • str {any}
    判断输入是否是字符串

think.isSymbol(any)

  • any {any}
    判断输入是否是 Symbol 类型

think.isUndefined(any)

  • any {any}
    判断输入是否是 undefined,也可以直接通过 xxx === undefined 来判断。

think.isRegExp(reg)

  • reg {any}
    判断输入是否是正则对象

think.isDate(date)

  • date {any}
    判断输入是否是日期对象

think.isError(error)

  • error {any}
    判断输入是否是Error类型

think.isFunction(any)

  • any {any}
    判断输入是否是函数类型

think.isPrimitive(any)

  • any {any}
    判断输入是否是原始类型,包含:nullstringbooleannumbersymbolundefined

think.isIP(ip)

  • ip {String}
    判断一个字符串是否是 ip 地址,IP v4 或者 IP v6,等同于 net.isIP

think.isBuffer(buffer)

  • buffer {any}
    判断输入是否是一个Buffer对象,等同于 Buffer.isBuffer

think.isIPv4(ip)

  • ip {String}
    判断一个字符串是否是 IP v4 地址,等同于 net.isIPv4

think.isIPv6(ip)

  • ip {String}
    判断一个字符串是否是 IP v6 地址,等同于 net.isIPv6

think.isMaster

判断当前进程是否为主进程,等同于 cluster.isMaster

think.isObject(obj)

  • obj {any}
    判断一个输入是否为 Object,通过 Object.prototype.toString.call(obj) 是否为 [object Object] 判断
  1. think.isObject({}); // true
  2. think.isObject([]); // false
  3. think.isObject(null); // false

think.promisify(fn, receiver)

  • fn {Function} 要包装的函数
  • receiver {Object} 要绑定作用域的对象
    此方法把一个 callback 函数包装 成Promise
  1. let fn = think.promisify(fs.readFile, fs);
  2. let data = await fn(__filename);

think.extend(target,…any)

  • target {Object} 要extend的目标对象
  • …any {Object} 可以有任意多个对象
    深拷贝对象,如果 key 相同,那么后面的值会覆盖前面的值。
  1. think.extend({a: 1}, {b: 2});
  2. // return {a:1,b:2};
  3. think.extend({a: 1}, {a: 2});
  4. // return {a: 2}

think.camelCase(str)

  • str {String}
    把字符串转成驼峰表示法
  1. think.camelCase('index_index');
  2. // return 'indexIndex'

think.snakeCase(str)

  • str {String}
    把驼峰写法转化为蛇形写法
  1. think.snakeCase('indexIndex');
  2. // return 'index_index'

think.isNumberString(str)

  • str {String}
    判断输入是不是一个字符串类型的数字
  1. think.isNumberString('419');
  2. // return true

think.isTrueEmpty(any)

  • any {any}
    判断是否是真正的空,undefinednull''NaN 为 true,其他为 false。
  1. think.isTrueEmpty(null);
  2. // return true

think.isEmpty(any)

  • any {any}
    判断对象是否为空, undefined, null ,'', NaN, [], {}, 0, false 为 true,其他为 false。
  1. think.isEmpty(null);
  2. // return true

think.defer()

生成一个 Deferred 对象。

  1. function test() {
  2. const defer = think.defer();
  3. setTimeout(function() {
  4. defer.reslove('1');
  5. },1000)
  6. return defer.promise
  7. }
  8. test().then((result)=>{
  9. resut === '1'
  10. })

think.omit(obj, props)

  • obj {Object} 要操作的对象
  • props {String | Array} 要忽略的属性,如果是字符串,多个值用逗号隔开
    忽略对象中的某些属性,返回新的对象
  1. const value = think.omit({a: 1, b: 2, c: 3}, 'a,b');
  2. // value is {c: 3}

think.md5(str)

  • str {String}
    计算字符串的 md5 值。

think.timeout(num)

  • num{Number} 时间,单位为毫秒
    将 setTimeout 包装为 Promise
  1. think.timeout(1000).then(()=>{
  2. ...
  3. })

think.escapeHtml(str)

  • str {String}
    对字符串进行 HTML 转义,转义 <>"' 字符。

think.datetime(date, format)

  • data {Date}
  • format {String} default 'YYYY-MM-DD HH:mm:ss'
    返回一个格式化日期
  1. think.datetime(1501406894849)
  2. // return "2017-07-30 17:28:14"

think.uuid(version)

  • version {String} v1|v4
  • return {String}
    生成 uuid 字符串,符合 RFC4122 规范,基于 uuid 模块。

think.ms(str)

  • str {String}
  • return {Number}
    把一个语义化的时间转成毫秒,如果转换失败则抛异常,使用 ms 库转换。
  1. think.ms('2 days') // 1d,10h,1y
  2. // return 172800000

think.isExist(path)

  • path {String}
    检测路径是否存在
  1. think.isExist('/usr/local/bin/node')
  2. // return true

think.isFile(filepath)

  • filepath {String}
    检测是否是一个文件路径
  1. think.isFile('/usr/local/bin/node')
  2. // return true

think.isDirectory(filepath)

  • filepath {String}
    检测是否是一个文件夹路径
  1. think.isDirectory('/usr/local/bin')
  2. // return true

think.chmod(path, mode)

  • path {String}
  • mode {String} default '0777'
    改变文件或文件夹的权限
  1. think.chmod('/usr/local/bin', '0775')

think.mkdir(path, mode)

  • path {String} 要创建的目录
  • mode {String} 文件夹权限,默认为 0777
  • return {Boolean}
    创建文件夹。创建成功返回 true, 失败返回 false。
  1. think.mkdir('/usr/local/bin/thinkjs', '0775')

think.getdirFiles(dir, prefix)

  • dir {String} 文件夹路径
  • prefix {String} 路径前缀
  • return {Array} 包含所有文件的数组
    获取文件夹下的所有文件。
  1. think.getdirFiles('/usr/local/bin')
  2. // return []

think.rmdir(path, reserve)

  • path {String}
  • reserve {Boolean} 是否保留当前的文件夹,只删除文件夹下的文件
    删除文件夹和文件夹下的文件,异步操作。
  1. think.rmdir('/usr/local/bin/thinkjs', true).then(()=>{
  2. console.log('删除完成')
  3. })

常见问题

think 对象是否推荐在插件里使用?

不建议在插件里(middleware、adapter、extend)里直接使用 think 对象,那样会让插件代码不方便单元测试。如果非要使用的话可以传入 app 对象,然后通过 app.think.xxx 来使用 think 对象上的属性或者方法。

  1. // src/config/middleware.js
  2. module.exports = [
  3. {
  4. handle: xxx
  5. }
  6. ];
  7. // xxx middleware
  8. module.exports = (options, app) => {
  9. return (ctx, next) => {
  10. // 通过 app.think.modules 获取项目的模块列表
  11. const modules = app.think.modules;
  12. // 如果是多模块项目下(单模块项目长度始终为 0)
  13. if(modules.length) {
  14. }
  15. }
  16. }

原文: https://thinkjs.org/zh-cn/doc/3.0/think.html