Node.js基础——模块

Node.js基础——模块,第1张

文章目录 在Vscode上使用node.js运行js代码法一:终端运行法二:右键Run Code Vsode设置node代码提示CommonJS规范——模块JS标准的缺陷CommonJS规范require使用require引入变量路径的两种表示方式 globaljs文件是运行在函数中的exports和module.exports的区别代码演示原理

在Vscode上使用node.js运行js代码 法一:终端运行

打开终端

在终端输入:node 文件路径\文件名

法二:右键Run Code


即可运行代码,得到结果:

Vsode设置node代码提示

打开vscode终端命令:

安装typings
npm install -g typings
安装nodejs的代码提示依赖
npm install @types/node

安装完成时候,输入代码就会有提示符了:

CommonJS规范——模块 JS标准的缺陷

JS是没有模块化系统(ES5)
模块化:就是将一个大的代码分成若干个小的代码,没有模块化的代码都是不可复用的。
JS有模块化,即一个js文件就可以看作是一个模块,但是如果模块2依赖于模块1那么必须先引入模块1,否则就会报错,所以说JS有模块但是没有模块化系统。。

标准库较少
如jQuery就不是标准库,是由程序员自主开发的

没有标准的接口

缺乏管理系统

CommonJS规范

CommonJS规范的提出,主要是为了弥补当前JavaScript没有标准的缺陷。
CommonJS对模块的定义十分简单∶

模块引用:在Node中通过require()函数来引入外部的模块。模块定义:在Node中一个js文件就是一个模块模块标识:就是可以唯一表示一个模块的东西
使用require()引入外部模块时,使用的路径就是模块标识 require

require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块
如果使用相对路径,必须以.或..开头
eg:

require('./hello.js')
使用require引入变量

注意使用require是无法将变量引入来的。
eg:hello.js

console.log('hello world')
var x = 100
var y = 200

01.js

require('./hello.js')
//后缀.js可以省略
console.log(x)

运行01.js,报如下错误:

解决该问需要进行两个修改:

require返回值
使用require()引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块。
所以我们设置变量接受这个对象,就可以接收引入模块传过来的变量了。
var md = require('./hello.js')
变量的可见性
接收完成之后还有一个问题是变量的可见性,我们输出md发现有如下结果:

md是一个空对象,这是由于变量的作用域问题导致变量的不可见。
在Node中,每一个js文件中的js代码都是独立运行在一个函数中,而不是全局作用域,所以一个模块的中使用var定义的的变量和函数在其他模块中无法访问。
(这里强调的是使用var,因为在JS中如果不使用var声明的变量就是全局变量)

即hello.js的代码我们可以看成是这样的:

(function (){
    console.log('hello world')
    var x = 100
    var y = 200
})()

所以我们要将变量暴露出去,设置成全局可见。
可以通过使用exports来进行设置:
只需要将需要暴露给外部的变量或方法设置为exports的属性即可.

所以,hello.js:

console.log('hello world')
exports.x = 100
exports.y = 200
exports.fn = function (){
    console.log('我是一个函数')
}

01.js:

var md = require('./hello.js')
console.log(md)
console.log(md.x)

输出:

路径的两种表示方式

模块分为核心模块和文件模块

核心模块:由node引擎提供的模块
核心模块的表示就是模块的名字,所以引入的时候直接写名字就可以了。
eg:
var fs = require("fs")
文件模块:由用户自己创建的模块
文件模块的表示就是文件的路径(绝对路径,相对路径),引入的时候就将文件的位置写上。 global

在node中有一个全局对象global,它的作用和网页中window类似
在全局中创建的变量都会作为global的属性保存
在全局中创建的函数都会作为global的方法保存

eg:

var a = 10
b = 100
console.log(global.a)
console.log(global.b)

输出:

undefined
100
js文件是运行在函数中的

之前我们说一个js文件是运行在一个函数中的,我们来验证一下

函数中才会有arguments参数
在js文件按中输出arguments:
console.log(arguments)

输出:

[Arguments] {
  '0': { x: 100, y: 200, fn: [Function (anonymous)] },
  '1': [Function: require] {
    resolve: [Function: resolve] { paths: [Function: paths] },
    main: Module {
      id: '.',
      path: 'c:\Users\86198\VScode\qianDuan\Node.js',
      exports: [Object],
      parent: null,
      filename: 'c:\Users\86198\VScode\qianDuan\Node.js\hello.js',
      loaded: false,
      children: [],
      paths: [Array]
    },
    extensions: [Object: null prototype] {
      '.js': [Function (anonymous)],
      '.json': [Function (anonymous)],
      '.node': [Function (anonymous)]
    },
    cache: [Object: null prototype] {
      'c:\Users\86198\VScode\qianDuan\Node.js\hello.js': [Module]
    }
  },
  '2': Module {
    id: '.',
    path: 'c:\Users\86198\VScode\qianDuan\Node.js',
    exports: { x: 100, y: 200, fn: [Function (anonymous)] },
    parent: null,
    filename: 'c:\Users\86198\VScode\qianDuan\Node.js\hello.js',
    loaded: false,
    children: [],
    paths: [
      'c:\Users\86198\VScode\qianDuan\Node.js\node_modules',
      'c:\Users\86198\VScode\qianDuan\node_modules',
      'c:\Users\86198\VScode\node_modules',
      'c:\Users\86198\node_modules',
      'c:\Users\node_modules',
      'c:\node_modules'
    ]
  },
  '3': 'c:\Users\86198\VScode\qianDuan\Node.js\hello.js',
  '4': 'c:\Users\86198\VScode\qianDuan\Node.js'
}
agruments.callee属性保存的是当前执行的函数对象,可以进行输出查看

验证:

console.log(arguments.callee)

输出:

[Function (anonymous)]

验证:

console.log(arguments.callee+"")
// 拼串会调用toString方法,显示函数结构

输出:

function (exports, require, module, __filename, __dirname) {
console.log(arguments.callee + "")
// 拼串会调用toString方法,显示函数结构
}

结论:在node执行模块的时候,它会将我们写的内容嵌套在如下函数中:

function (exports, require, module, __filename, __dirname) {
     自己写的代码内容
}

我们直接使用的exports, require变量也是通过这个函数传过来的
参数解析:
- exports:该对象用来将变量或函数暴露到外部
- require:函数,用来引入外部的模块
- module:module代表的是当的模块本身,exports就是module的属性

console.log(module.exports == exports)

结果:True
- __filename:表示的是当前模块(js文件)的完整路径
- __dirname:表示的是当前模块所在文件夹的完整路径
eg:

console.log(__filename)
console.log(__dirname)

输出:

c:\Users\86198\VScode\qianDuan\Node.js\01module.js
c:\Users\86198\VScode\qianDuan\Node.js
exports和module.exports的区别

两者着本质上是一个对象,但是:

通过exports只能使用.的方式来向外暴露内部变量
exports.XXX=XXXmodule.exports既可以通过.的形式,也可以直接赋值
module.exports.XXX=XXX
module.exports = {} 代码演示

**示例一:**都可以使用.的方式来向外暴露内部变量
hello.js:

exports.name1 = '孙悟空'
module.exports.name2 = '猪八戒'

01.js:

var hello = require('./hello')
console.log(hello.name1)
console.log(hello.name2)

输出:

孙悟空
猪八戒

示例二: module.exports可以通过直接赋值暴露对象,而exports不可以
当给module.exports赋值的时候可以访问到:
hello.js

module.exports = {
    name2:'猪八戒'
} 

01.js:

var hello = require('./hello')
console.log(hello.name2)

输出:

猪八戒

当给exports赋值的时候可以不访问到:
hello.js

exports = {
    name2:'猪八戒'
} 

01.js

var hello = require('./hello')
console.log(hello.name2)

输出:

undefined
原理

原因其实很简单,变量指向的问题,实际上对外暴露是 module.exports 起的作用,而exports是因为指向它才具有暴露对象的能力。
如果给module.exports赋值,就是在里面定义向外暴露的对象;
而给exports赋值,exports就不指向module.exports,就无法定义向外暴露的对象了。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1322213.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-12
下一篇2022-06-12

发表评论

登录后才能评论

评论列表(0条)

    保存