插入Boolean类型的节点 
Boolean在js中是一个基础类型,没有什么特别需要注意的地方,在我们日常的开发工作中,我们一般会有以下几种方法声明一个Boolean类型的变量。
字面量声明
javascriptvar bool1 = false使用
new关键字javascriptvar bool2 = new Boolean(false)使用拆箱转换
javascriptvar bool3 = !!1
这些方法都是日常工作中使用的比较多的方法,下面就是我们使用types创建Boolean类型节点的方法。
使用字面量
javascript/** * @NOTE 声明一个值为false的变量bool1 * var bool1 = false */ const bool1 = t.variableDeclaration('const', [ t.variableDeclarator(t.identifier('bool1'), t.booleanLiteral(false)) ])这一段我们需要认识一个新的函数
booleanLiternal,用于新增一个Boolean类型的字面量。对于基础类型,从Number类型开始,我们就大致上发现了一个规律,每一个基础数据类型,types都会准备一个单独的字面量函数,用于创建对应的基础类型值。到目前为止,我们已经认识到了以下几种声明字面量的函数,已经覆盖了JS中的全部的基础类型:
类型 使用函数 NumericLiteral t.numericLiteral(value) StringLiteral t.stringLiteral(value) BooleanLiteral t.booleanLiteral(value) NullLiteral t.nullLiteral() Identifier t.identifier(name) 使用new关键字实例化
javascript/** * @NOTE 使用new关键字创建 * var bool2 = new Boolean(false) */ const newNode = t.newExpression(t.identifier('Boolean'), [ t.booleanLiteral(false) ]) const bool2 = t.variableDeclaration('const', [ t.variableDeclarator(t.identifier('bool2'), newNode) ])继续使用我们之前已经使用的过的函数
newExpression表达式,和上面提到的声明Boolean字面量的函数booleanLiternal。使用拆箱转换
javascript/** * @NOTE 使用拆箱转换 * var bool3 = !!1 */ const unaryNode = t.unaryExpression('!', t.numericLiteral(1), true) const unaryNode1 = t.unaryExpression('!', unaryNode, true) const bool3 = t.variableDeclaration('const', [ t.variableDeclarator(t.identifier('bool3'), unaryNode1) ])这里我们需要认识一个新函数
unaryExpress单目表达式,用于单目运算符。运算符 描述 使用函数 + 对数字类型执行正号操作,对数字字符串类型进行强制类型转换 t.unaryExpression - 对数字类型执行负号操作,对数字字符串类型进行强制类型转换并执行负号操作 t.unaryExpression ! 对布尔值进行逻辑非运算,将非布尔值操作数转换成布尔值 t.unaryExpression ~ 对 32 位带符号整数执行按位取反操作 t.unaryExpression ++ 对变量执行递增操作,前缀形式和后缀形式均可使用 t.updateExpression -- 对变量执行递减操作,前缀形式和后缀形式均可使用 t.updateExpression typeof 返回操作数的数据类型 t.unaryExpression void 对表达式求值并返回 undefinedt.unaryExpression delete 删除对象的属性 t.unaryExpression await 等待一个 Promise 对象的解决,只能用于异步函数中 t.awaitExpression yield 将生成器函数的执行暂停,并返回一个值 t.yieldExpression 
在这里回到主题,可以看上表,没有针对!!双逻辑非的表达式,但是我们可以将它看做两个逻辑非组合在一起。所以我们可以在例3中看到我们是怎么实现的双非逻辑符。
对于自加/自减运算符,我们可以直接使用types提供的updateExpression表达式实现其逻辑。这里我们必须将其区分开++/--与!!是两回事,在js中没有对!!的定义,它本身就是一个组合表达式。
除了await与yield语句,这两个语句我们将在Functoin中出现具体的例子,其他的单目运算符都已经出现在下面的例子当中了。
import core from '@babel/core'
import fs from 'fs-extra'
import t from '@babel/types'
const filepath = './demo.js'
const workflow = async () => {
  const source = await fs.readFile(filepath, { encoding: 'utf-8' })
  const ast = await core.parse(source, { sourceType: 'module' })
  /**
   * @NOTE 使用 + 运算符
   * 
   * var node1 = +1
   */
  const unaryNode1 = t.variableDeclaration('const', [
    t.variableDeclarator(t.identifier('node1'), t.unaryExpression('+', t.numericLiteral(1), true))
  ])
  /**
   * @NOTE 使用 - 运算符
   * var node2 = -1
   */
  const unaryNode2 = t.variableDeclaration('const', [
    t.variableDeclarator(t.identifier('node2'), t.unaryExpression('-', t.numericLiteral(1), true))
  ])
  /**
   * @NOTE 自增与自减 同理
   * var node3 = ++1
   * var node4 = --1
   */
  const increateNode = t.updateExpression('++', t.numericLiteral(1), true)
  const unaryNode3 = t.variableDeclaration('const', [
    t.variableDeclarator(t.identifier('node3'), increateNode)
  ])
  /**
   * @NOTE 实现取反的逻辑操作符
   * 
   * var node4 = !1
   */
  const unaryNode4 = t.variableDeclaration('const', [
    t.variableDeclarator(t.identifier('node4'), t.unaryExpression('!', t.numericLiteral(1), true))
  ])
  /**
   * @NOTE 派生操作 实现!!
   */
  const node5C = t.unaryExpression('!', t.numericLiteral(1), true)
  const node5 = t.unaryExpression('!', node5C, true)
  const unaryNode5 = t.variableDeclaration('const', [
    t.variableDeclarator(t.identifier('node5'), node5)
  ])
  /**
   * @NOTE 实现typeof
   * typeof 1
   */
  const typeofNode = t.variableDeclaration('const', [
    t.variableDeclarator(t.identifier('typeofNode'), t.unaryExpression('typeof', t.numericLiteral(1), true))
  ])
  /**
   * @NOTE 实现delete 操作符
   * delete obj.name
   */
  const deleteNode = t.unaryExpression('delete', t.memberExpression(t.identifier('obj'), t.identifier('name')))
  ast.program.body.push(unaryNode1, unaryNode2, unaryNode3, unaryNode4, unaryNode5, typeofNode, deleteNode)
  const output = await core.transformFromAstSync(ast)
  console.log('=======> workflow.ast', output.code)
}
workflow()现在我们已经基本上将基础类型、复杂类型和单目运算符都过了一遍,在这个基础上,我们将继续学习Function类型。在JS中我们Object与Function是最复杂的两块内容,里面东西最多,有继承链、原型链、闭包和异步函数,只要我们掌握了这些内容,就可以直接说精通js啦。
源码地址: