Node模块的作用域

1,519 阅读5分钟

1. 全局作用域和局部作用域

  • 作用域:规定一个变量和函数可以使用的范围,作用域分为两种,全局作用域和局部作用域
  • 全局作用域:直接编写在script标签中,或者单独的一个js文件中的代码,都是全局作用域。全局作用域在页面创建时打开,在页面关闭时销毁。在前端js中,在全局作用域中有一个全局对象 window(代表的是一个浏览器的窗口,由浏览器创建),可以直接使用。在Node中,有一个全局对象global。
  • 局部作用域:在函数内部就是局部作用域,这个代码的名字只在函数的内部起作用,调用函数时创建函数作用域,函数执行完毕之后,函数作用域销毁;每调用一次函数就会创建一个新的函数作用域,它们之间是相互独立的。

2.Node.js的作用域

  • 在Node中,每一个js文件都是一个单独的作用域,因为node的模块化会将每一个文件中的代码封装在一个函数内部,这和浏览器开发不同,浏览器中,var a,此时a会自动成为window的属性,此时js文件和js文件共享作用域,但是Node.js中,每个js文件是独立的作用域不共享,所以Node中每一个文件中的变量都是私有的。

    编写以下代码:

    var num = 10;
    

    node在执行前会将该模块编译成一个函数:function(exports,require,module,__filename,__dirname){var num=10}

     var num = 10;
     console.log(arguments);//打印当前模块的组成信息
     console.log(arguments.callee.toString()); //打印的函数体
    

  • 所有用户编写的代码都自动封装一个函数中,函数有五个参数,我们就可以在函数内部使用五个实参

    exportsrequire是通过参数来传递的,如果参数是引用类型,那么一个地方发生改变,其它地方也会跟着发生改变。

  • 暴露模块数据:让其它作用域使用本作用域中的值

    使用exports暴露,这里输入的值是被输出的值的拷贝,一旦输出一个值,模块内部的变化就是影响不到该值(仅仅是普通的值,如果是引用类型的值,还是会受影响的)

    exports暴露数据,引入时,必须通过对象去拿,可以暴露多个数据

     let a = 100
     exports.a = a//exports是一个对象,给这个对象添加了一个属性a,a的值就是本作用域的变量值
    

    使用module.exports暴露数据

    module.exports暴露数据,暴露的什么,引入的就是什么,只能暴露一个东西(类,构造函数等)

    function Student(name,age,sex){this.name = name;this.age = age;this.sex = sex}
    module.exports = Student
    //引入
    let stu = require("./a.js")
    var xiaoming = new stu("小明",18,"male") 若使用exports,则需要var xiaoming = new stu.Student("",18,"")
    

    使用全局变量暴露数据

    	var username = 'xiaoming
       	global.name = username
    

    使用时可以不写global,直接使用name

3.模块的共性

  • 所有的模块化都有一个共性,模块的功能都是把代码放到一个独立的函数中
  • 模块中使用var定义的变量都是局部变量
  • 模块中定义的函数也是局部的
  • 模块有一个模块对象,包含moduleName(模块名),exports(导出对象)
  • 如果模块中需要 暴露方法或者属性给外部使用,那么就是往exports对象添加属性
  • 导入一个模块使用require('moduleName'),该方法返回是模块对象的exports对象

4.node全局作用域与全局函数

  • 自定义全局变量或方法
	global.aa = 10
	global.add = (a,b) => a +b;
  • 内置的全局方法

    ① Timout函数 与clearTimeout函数 设置与清除延迟定时器. 与浏览器的延时定时不同,node中的延时方法第一个参数不能是字符串

    setTimeout(function () {
      console.log(1111)
    }, 2000)
    

    ② setInterval函数与 clearInterval函数 设置与清除间隔(循环)定时器

    setInterval(function () {
      console.log(1111)
    }, 2000)
    

    ③ setImmediate 函数与clearImmediate 函数 类似于定时,但是setImmediate 函数是在当前时间轮询末尾处执行

    setImmediate(() => {
      console.log(123)
    })
    

5.process进程

  • process是Node中的一个全局对象属性, 可以在任何模块中使用, 该对象具有一些可以用来获取Node.js应用程序以及运行该应用程序的用户,运行环境的各种信息的属性,方法与事件

  • process.argv属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数,如果不传参数,返回一个数组,数组第一项是当前node文件路径,第二个是运行文件的路径。

  • execPath 属性,启动 Node.js 进程的可执行文件的绝对路径名,就是process.argv数组中的第一个值.

  • process.env属性返回一个包含用户环境信息的对象,在process.env中新增一个属性,会将属性值转换成字符串

  • cwd方法 返回 Node.js 进程的当前工作的目录路径

  • nextTick 方法

    第一个参数必填, 是回调函数 第二个之后的参数可选, 就是第二回调函数的参数

    process.nextTick() 方法将 callback 添加到下一个时间点的队列。 在 JavaScript 堆栈上的当前操作运行完成之后以及允许事件循环继续之前,此队列会被完全耗尽。 如果要递归地调用 process.nextTick(),则可以创建无限的循环

    console.log('开始');   // 1
    process.nextTick(() => {
      console.log('下一个时间点的回调');  // 3
    });
    console.log('调度');  // 2
    
      process.nextTick(() => {
      console.log('下一个时间点的回调')
      })
    
      setImmediate(() => {
          console.log("setImediate")
      })
    
      setTimeout(() => {
          console.log("setTimeout")
      })