Nodejs面试题

1、Node模块机制

1.1 请介绍一下node里的模块是什么

Node中,每个文件模块都是一个对象,它的定义如下:

1

2

3

4

5

6

7

8

9

10

11

12

function Module(id, parent) {

 this.id = id;

 this.exports = {};

 this.parent = parent;

 this.filename = null;

 this.loaded = false;

 this.children = [];

}

module.exports = Module;

var module = new Module(filename, parent);

所有的模块都是 Module 的实例。可以看到,当前模块(module.js)也是 Module 的一个实例。

1.2 请介绍一下require的模块加载机制

这道题基本上就可以了解到面试者对Node模块机制的了解程度基本上面试提到

1、先计算模块路径

2、如果模块在缓存里面,取出缓存

3、加载模块

4、的输出模块的exports属性即可

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

// require 其实内部调用 Module._load 方法

Module._load = function(request, parent, isMain) {

 // 计算绝对路径

 var filename = Module._resolveFilename(request, parent);

 // 第一步:如果有缓存,取出缓存

 var cachedModule = Module._cache[filename];

 if (cachedModule) {

 return cachedModule.exports;

 // 第二步:是否为内置模块

 if (NativeModule.exists(filename)) {

 return NativeModule.require(filename);

 }

  

 /********************************这里注意了**************************/

 // 第三步:生成模块实例,存入缓存

 // 这里的Module就是我们上面的1.1定义的Module

 var module = new Module(filename, parent);

 Module._cache[filename] = module;

 /********************************这里注意了**************************/

 // 第四步:加载模块

 // 下面的module.load实际上是Module原型上有一个方法叫Module.prototype.load

 try {

 module.load(filename);

 hadException = false;

 } finally {

 if (hadException) {

  delete Module._cache[filename];

 }

 }

 // 第五步:输出模块的exports属性

 return module.exports;

};

接着上一题继续发问

1.3 加载模块时,为什么每个模块都有__dirname,__filename属性呢,new Module的时候我们看到1.1部分没有这两个属性的,那么这两个属性是从哪里来的

1

2

3

4

5

6

7

8

9

10

11

// 上面(1.2部分)的第四步module.load(filename)

// 这一步,module模块相当于被包装了,包装形式如下

// 加载js模块,相当于下面的代码(加载node模块和json模块逻辑不一样)

(function (exports, require, module, __filename, __dirname) {

 // 模块源码

 // 假如模块代码如下

 var math = require('math');

 exports.area = function(radius){

  return Math.PI * radius * radius

 }

});

也就是说,每个module里面都会传入__filename, __dirname参数,这两个参数并不是module本身就有的,是外界传入的

1.4 我们知道node导出模块有两种方式,一种是exports.xxx=xxx和Module.exports={}有什么区别吗

  • exports其实就是module.exports
  • 其实1.3问题的代码已经说明问题了,接着我引用廖雪峰大神的讲解,希望能讲的更清楚

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

module.exports vs exports

很多时候,你会看到,在Node环境中,有两种方法可以在一个模块中输出变量:

方法一:对module.exports赋值:

// hello.js

function hello() {

 console.log('Hello, world!');

}

function greet(name) {

 console.log('Hello, ' + name + '!');

}

module.exports = {

 hello: hello,

 greet: greet

};

方法二:直接使用exports:

// hello.js

function hello() {

 console.log('Hello, world!');

}

function greet(name) {

 console.log('Hello, ' + name + '!'

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值