nodejs(第三篇):nodejs中的文件模块、nodejs中的require与exports、http模块补充、JavaScript Standard Style

一、nodejs中的文件模块

在nodejs中,用户自己编写的模块,称为文件模块

文件模块,则是指js文件、json文件或者是.node文件。在引用文件模块的时候后要加上文件的路径:/.../.../xxx.js表示绝对路径、./xxx.js表示相对路径(同一文件夹下的xxx.js),../表示上一级目录。如果既不加/.../、../又不加./的话,则该模块要么是核心模块,要么是从一个node_modules文件夹加载。

(1)在Node.js中,require是一个方法,只有通过require方法来加载执行多个JavaScript脚本文件。

自定义模块相对路径必须写 . / ,可以省略后缀名js。

demo

在同一文件夹test下,创建a.js、b.js

分别写入内容

a.js内容:

console.log(‘a start‘)
require(‘./b‘)
console.log(‘a end‘)

b.js内容

console.log(‘b msg‘)

执行a.js,输出结果

ERROR: The process "node.exe" not found.
a start
b msg
a end
[Finished in 0.5s]

分析:require加载b.js中的代码,是执行其中的代码

(2)require加载只能是执行其中的代码,模块作用域是隔离的

文件与文件之间由于是模块作用域(在Node.js中没有全局作用域的概念),模块是完全封闭的,外部无法访问内部,内部也无法范访问外部。

测试1:测试文件模块之间值是否相互影响或者被覆盖

在同一文件夹test下,创建a.js、b.js

分别写入内容

a.js内容:

var foo = ‘aaa‘
console.log(‘a start‘)
require(‘./b‘)
console.log(‘a end‘)
console.log(‘foo 的值是:‘, foo)

b.js内容

console.log(‘b msg‘)
var foo = ‘bbb‘
console.log(‘b end‘)

执行a.js,输出结果

ERROR: The process "node.exe" not found.
a start
b msg
b end
a end
foo 的值是: aaa
[Finished in 0.4s]

分析:从输出结果可以看出,引入的b.js并没有影响a.js中的foo的值,文件与文件之间模块作用域是隔离的

测试2:在被引入的文件模块中调用原文件模块里的函数

在同一文件夹test下,创建a.js、b.js

分别写入内容

a.js内容:


console.log(‘a start‘)

function add(x, y) {
  return x + y
}

require(‘./b‘)
console.log(‘a end‘)

b.js内容

console.log(‘b msg‘)
console.log(add(10, 20))
console.log(‘b end‘)

执行a.js,输出结果执行报错,add is not defined,函数未被定义,无法引用原文件模块的函数

二、nodejs中的require与exports

require

require函数用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象。模块名可使用相对路径(以./开头),或者是绝对路径(以/C:之类的盘符开头)。另外,模块名中的.js扩展名可以省略。以下是一个例子。

require 方法有两个作用:

  1. 加载文件模块并执行里面的代码
  2. 拿到被加载文件模块导出的接口对象
var foo1 = require(‘./foo‘);
var foo2 = require(‘./foo.js‘);
var foo3 = require(‘/home/user/foo‘);
var foo4 = require(‘/home/user/foo.js‘);

// foo1至foo4中保存的是同一个模块的导出对象。

另外,可以使用以下方式加载和使用一个JSON文件。

var data = require(‘./data.json‘);

exports

exports对象是当前模块的导出对象,用于导出模块公有方法和属性。别的模块通过require函数使用当前模块时得到的就是当前模块的exports对象。以下例子中导出了一个公有方法。

在每个文件模块中都提供了一个对象:exports

exports 默认是一个空对象

你要做的就是把所有需要被外部访问的成员挂载到这个 exports 对象中

exports.hello = function () {
    console.log(‘Hello World!‘);
};

测试

在同一文件夹test下,创建a.js、b.js

分别写入内容

a.js内容:

var bExports = require(‘./b‘) //引入b文件处理模块

console.log(bExports.foo) //从require对象中接收到foo属性的值

console.log(bExports.add(10, 30))//从require对象中接收到add函数

console.log(bExports.age)  //未能接收到age属性,所以输出值是undefined

bExports.readFile(‘./a.js‘)  //这里执行的是b.js的readFile函数,与fs模块中的
//readFile函数无关

console.log(‘------分割线-------‘)

var fs = require(‘fs‘)  //引入fs文件处理模块

fs.readFile(‘./a.js‘, function (err, data) {
	//执行fs模块的readFile方法
  if (err) {
    console.log(‘读取文件失败‘)
  } else {
    console.log(data.toString())
  }
})

b.js内容

var foo = ‘bbb‘

// console.log(exports)

exports.foo = ‘hello‘

exports.add = function (x, y) {
  return x + y
}

exports.readFile = function (path, callback) {
  console.log(‘文件路径:‘, path)
}

var age = 18

// exports.age = age

function add(x, y) {
  return x - y
}

执行a.js,输出结果

ERROR: The process "node.exe" not found.
hello
40
undefined
文件路径: ./a.js
------分割线-------
var bExports = require(‘./b‘) //引入b文件处理模块

console.log(bExports.foo) //从require对象中接收到foo属性的值

console.log(bExports.add(10, 30))//从require对象中接收到add函数

console.log(bExports.age)  //未能接收到age属性,所以输出值是undefined

bExports.readFile(‘./a.js‘)  //这里执行的是b.js的readFile函数,与fs模块中的
//readFile函数无关

console.log(‘------分割线-------‘)

var fs = require(‘fs‘)  //引入fs文件处理模块

fs.readFile(‘./a.js‘, function (err, data) {
	//执行fs模块的readFile方法
  if (err) {
    console.log(‘读取文件失败‘)
  } else {
    console.log(data.toString())
  }
})

[Finished in 0.4s]

分析:a.js通过bExports接收b.js通过exports`对象挂载的属性和函数,没有则显示undefined

三、http模块补充

设置响应头

res.setHeader()

var http = require(‘http‘)

var server = http.createServer()

server.on(‘request‘, function (req, res) {
  // 在服务端默认发送的数据,其实是 utf8 编码的内容
  // 但是浏览器不知道你是 utf8 编码的内容
  // 浏览器在不知道服务器响应内容的编码的情况下会按照当前操作系统的默认编码去解析
  // 中文操作系统默认是 gbk
  // 解决方法就是正确的告诉浏览器我给你发送的内容是什么编码的
  // 在 http 协议中,Content-Type 就是用来告知对方我给你发送的数据内容是什么类型
  // res.setHeader(‘Content-Type‘, ‘text/plain; charset=utf-8‘)
  // res.end(‘hello 世界‘)

  var url = req.url

  if (url === ‘/plain‘) {
    // text/plain 就是普通文本
    res.setHeader(‘Content-Type‘, ‘text/plain; charset=utf-8‘)
    //设置响应头
    res.end(‘hello 世界‘)
  } else if (url === ‘/html‘) {
    // 如果你发送的是 html 格式的字符串,则也要告诉浏览器我给你发送是 text/html 格式的内容
    res.setHeader(‘Content-Type‘, ‘text/html; charset=utf-8‘)
    res.end(‘<p>hello html <a href="">点我</a></p>‘)
  }
})

server.listen(3000, function () {
  console.log(‘Server is running...‘)
})

fs模块与http模块结合

通过网络发送文件( http结合fs发送文件中的数据):发送的并不是文件,本质上发送的是文件的内容,当浏览器收到服务器响应内容之后,就会根据Content-Type进行对应的解析处理

// 1. 结合 fs 发送文件中的数据
// 2. Content-Type
//    http://tool.oschina.net/commons
//    不同的资源对应的 Content-Type 是不一样的
//    图片不需要指定编码
//    一般只为字符数据才指定编码

var http = require(‘http‘)
var fs = require(‘fs‘)

var server = http.createServer()

server.on(‘request‘, function (req, res) {
  // / index.html
  var url = req.url

  if (url === ‘/‘) {
    // 肯定不这么干
    // res.end(‘<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><h1>首页</h1></body>/html>‘)

    // 我们要发送的还是在文件中的内容
    fs.readFile(‘./resource/index.html‘, function (err, data) {
      if (err) {
        res.setHeader(‘Content-Type‘, ‘text/plain; charset=utf-8‘)
        res.end(‘文件读取失败,请稍后重试!‘)
      } else {
        // data 默认是二进制数据,可以通过 .toString 转为咱们能识别的字符串
        // res.end() 支持两种数据类型,一种是二进制,一种是字符串
        res.setHeader(‘Content-Type‘, ‘text/html; charset=utf-8‘)
        res.end(data)
      }
    })
  } else if (url === ‘/xiaoming‘) {
    // url:统一资源定位符
    // 一个 url 最终其实是要对应到一个资源的
    fs.readFile(‘./resource/ab2.jpg‘, function (err, data) {
      if (err) {
        res.setHeader(‘Content-Type‘, ‘text/plain; charset=utf-8‘)
        res.end(‘文件读取失败,请稍后重试!‘)
      } else {
        // data 默认是二进制数据,可以通过 .toString 转为咱们能识别的字符串
        // res.end() 支持两种数据类型,一种是二进制,一种是字符串
        // 图片就不需要指定编码了,因为我们常说的编码一般指的是:字符编码
        res.setHeader(‘Content-Type‘, ‘image/jpeg‘)
        res.end(data)
      }
    })
  }
})

server.listen(3000, function () {
  console.log(‘Server is running...‘)
})

四、JavaScript Standard Style(Js 标准编码风格)

使用两个空格?– 进行缩进

字符串使用单引号?– 需要转义的地方除外

不再有冗余的变量?– 这是导致?大量?bug 的源头!

行首不要以?(,?[, or?`?开头

这是省略分号时唯一会造成问题的地方 –?工具里已加了自动检测!

关键字后加空格?if (condition) { ... }

函数名后加空格?function name (arg) { ... }

坚持使用全等?===?摒弃?==?一但在需要检查?null || undefined?时可以使用?obj == null。

一定要处理 Node.js 中错误回调传递进来的?err?参数。

使用浏览器全局变量时加上?window?前缀 –?document?和?navigator?除外

避免无意中使用到了这些命名看上去很普通的全局变量,?open,?length, event?还有?name。

// 当你采用了无分号的代码风格的时候,只需要注意以下情况就不会有上面的问题了:
//    当一行代码是以:
//        (
//        [
//        `
//        开头的时候,则在前面补上一个分号用以避免一些语法解析错误。
//    所以你会发现在一些第三方的代码中能看到一上来就以一个 ; 开头。
//  结论:
//    无论你的代码是否有分号,都建议如果一行代码是以 (、[、` 开头的,则最好都在其前面补上一个分号。
//    有些人也喜欢玩儿一些花哨的东西,例如可以使用 ! ~ 等。

细则

  • 使用两个空格 进行缩进
function hello (name) {
  console.log(‘hi‘, name)
}
  • 除需要转义的情况外,字符串统一使用单引号
console.log(‘hello there‘)
$("<div class=‘box‘>")
  • 不要留下未使用的变量
function myFunction () {
  var result = something()   // ? avoid
}
  • 关键字后面加空格
if (condition) { ... }   // ? ok
if(condition) { ... }    // ? avoid
  • 函数声明时括号与函数名间加空格
function name (arg) { ... }   // ? ok
function name(arg) { ... }    // ? avoid

run(function () { ... })      // ? ok
run(function() { ... })       // ? avoid
  • 始终使用 === 替代 ==

例外:obj == null 可以用来检查 null || undefined

if (name === ‘John‘)   // ? ok
if (name == ‘John‘)    // ? avoid

if (name !== ‘John‘)   // ? ok
if (name != ‘John‘)    // ? avoid
  • 字符串拼接操作符(Infix operators)之间要留空格
// ? ok
var x = 2
var message = ‘hello, ‘ + name + ‘!‘

// ? avoid
var x=2
var message = ‘hello, ‘+name+‘!‘
  • 逗号后面加空格
// ? ok
var list = [1, 2, 3, 4]
function greet (name, options) { ... }

// ? avoid
var list = [1,2,3,4]
function greet (name,options) { ... }
  • else 关键字要与花括号保持在同一行
// ? ok
if (condition) {
  // ...
} else {
  // ...
}

// ? avoid
if (condition) {
  // ...
}
else {
  // ...
}
  • 多行if语句的括号不能省
// ? ok
if (options.quiet !== true) console.log(‘done‘)

// ? ok
if (options.quiet !== true) {
  console.log(‘done‘)
}

// ? avoid
if (options.quiet !== true)
  console.log(‘done‘)
  • 使用浏览器全局变量时加上 window. 前缀

例外: document, console , navigator

window.alert(‘hi‘)   // ? ok
  • 不允许有连续多行的空行
// ? ok
var value = ‘hello world‘
console.log(value)
// ? avoid
var value = ‘hello world‘

console.log(value)
  • 对于三元运算符 ? 和 : 与他们所负责的代码处于同一行
// ? ok
var location = env.development ? ‘localhost‘ : ‘www.api.com‘

// ? ok
var location = env.development
  ? ‘localhost‘
  : ‘www.api.com‘

// ? avoid
var location = env.development ?
  ‘localhost‘ :
  ‘www.api.com‘
  • 每个 var 关键字单独声明一个变量
// ? ok
var silent = true
var verbose = true

// ? avoid
var silent = true, verbose = true

// ? avoid
var silent = true,
    verbose = true
  • 单行代码块两边加空格
function foo () {return true}    // ? avoid
function foo () { return true }  // ? ok
  • 对于变量和函数名统一使用驼峰命名法
function my_function () { }    // ? avoid
function myFunction () { }     // ? ok

var my_var = ‘hello‘           // ? avoid
var myVar = ‘hello‘            // ? ok
  • 不允许有多余的行末逗号
var obj = {
  message: ‘hello‘,   // ? avoid
}
  • 始终将逗号置于行末
var obj = {
  foo: ‘foo‘
  ,bar: ‘bar‘   // ? avoid
}

var obj = {
  foo: ‘foo‘,
  bar: ‘bar‘   // ? ok
}
  • 点号操作符须与属性处在同一行
  console.
    log(‘hello‘)  // ? avoid

  console
    .log(‘hello‘) // ? ok
  • 文件末尾留一空行
  • 函数调用时标识符与括号间不留间隔
console.log (‘hello‘) // ? avoid
console.log(‘hello‘)  // ? ok
  • 键值对当中冒号与值之间要留空白
var obj = { ‘key‘ : ‘value‘ }    // ? avoid
var obj = { ‘key‘ :‘value‘ }     // ? avoid
var obj = { ‘key‘:‘value‘ }      // ? avoid
var obj = { ‘key‘: ‘value‘ }     // ? ok
  • 构造函数要以大写字母开头
function animal () {}
var dog = new animal()    // ? avoid

function Animal () {}
var dog = new Animal()    // ? ok
  • 使用数组字面量而不是构造器
var nums = new Array(1, 2, 3)   // ? avoid
var nums = [1, 2, 3]            // ? ok
  • 避免修改使用 const 声明的变量
const score = 100
score = 125       // ? avoid
  • 避免使用常量作为条件表达式的条件(循环语句除外)
if (false) {    // ? avoid
  // ...
}

if (x === 0) {  // ? ok
  // ...
}

while (true) {  // ? ok
  // ...
}
  • 同一模块有多个导入时一次性写完
import { myFunc1 } from ‘module‘
import { myFunc2 } from ‘module‘          // ? avoid

import { myFunc1, myFunc2 } from ‘module‘ // ? ok
  • 不要扩展原生对象
Object.prototype.age = 21     // ? avoid
  • switch 一定要使用 break 来将条件分支正常中断
switch (filter) {
  case 1:
    doSomething()    // ? avoid
  case 2:
    doSomethingElse()
}

switch (filter) {
  case 1:
    doSomething()
    break           // ? ok
  case 2:
    doSomethingElse()
}

switch (filter) {
  case 1:
    doSomething()
    // fallthrough  // ? ok
  case 2:
    doSomethingElse()
}
  • 不要对全局只读对象重新赋值
window = {}     // ? avoid
  • 不要混合使用空格与制表符作为缩进
  • 除了缩进,不要使用多个空格
const id =    1234    // ? avoid
const id = 1234       // ? ok
  • new 创建对象实例后需要赋值给变量
new Character()                     // ? avoid
const character = new Character()   // ? ok
  • 禁止使用 Function 构造器
var sum = new Function(‘a‘, ‘b‘, ‘return a + b‘)    // ? avoid
  • 禁止使用 Object 构造器
let config = new Object()   // ? avoid
  • 使用 __dirname 和 __filename 时尽量避免使用字符串拼接
const pathToFile = __dirname + ‘/app.js‘            // ? avoid
const pathToFile = path.join(__dirname, ‘app.js‘)   // ? ok
  • 不要重复声明变量
let name = ‘John‘
let name = ‘Jane‘     // ? avoid

let name = ‘John‘
name = ‘Jane‘         // ? ok
  • return 语句中的赋值必需有括号包裹
function sum (a, b) {
  return result = a + b     // ? avoid
}

function sum (a, b) {
  return (result = a + b)   // ? ok
}
  • return,throw,continue 和 break 这些语句后面的代码都是多余的
function doSomething () {
  return true
  console.log(‘never called‘)     // ? avoid
}
  • 展开运算符与它的表达式间不要留空白
fn(... args)    // ? avoid
fn(...args)     // ? ok
  • 分号前面不留空格,后面留空格
for (let i = 0 ;i < items.length ;i++) {...}    // ? avoid
for (let i = 0; i < items.length; i++) {...}    // ? ok
  • 代码块开始之前留一个空格
if (admin){...}     // ? avoid
if (admin) {...}    // ? ok
  • 圆括号间不留空格
getName( name )     // ? avoid
getName(name)       // ? ok
  • 注释前后留空格
//comment           // ? avoid
// comment          // ? ok

/*comment*/         // ? avoid
/* comment */       // ? ok
  • 模板字符串中变量前后不加空格
const message = `Hello, ${ name }`    // ? avoid
const message = `Hello, ${name}`      // ? ok
  • 检查 NaN 的正确姿势是使用 isNaN()
if (price === NaN) { }      // ? avoid
if (isNaN(price)) { }       // ? ok

关于分号

  • 不要使用分号
window.alert(‘hi‘)   // ? ok
window.alert(‘hi‘);  // ? avoid
  • 不要使用 (, [, or ``` 等作为一行的开始。在没有分号的情况下代码压缩后会导致报错,而坚持这一规范则可避免出错。
// ? ok
;(function () {
  window.alert(‘ok‘)
}())

// ? avoid
(function () {
  window.alert(‘ok‘)
}())
// ? ok
;[1, 2, 3].forEach(bar)

// ? avoid
[1, 2, 3].forEach(bar)
// ? ok
;`hello`.indexOf(‘o‘)

// ? avoid
`hello`.indexOf(‘o‘)

上面的写法只能说聪明过头了

比如:

;[1, 2, 3].forEach(bar)

建议的写法是:

var nums = [1, 2, 3]
nums.forEach(bar)

参考资料

[1]https://www.jianshu.com/p/e889069b7c27

[2]https://github.com/standard/standard/blob/master/docs/RULES-zhcn.md

原文地址:https://www.cnblogs.com/Nicholas0707/p/12571457.html

时间: 2024-12-24 01:02:18

nodejs(第三篇):nodejs中的文件模块、nodejs中的require与exports、http模块补充、JavaScript Standard Style的相关文章

C#中 dll文件放在子目录中的方法

VS2012-C# dll文件直接放在程序根目录中(和exe文件一起)比较乱,可以将dll文件放在子文件夹中.步骤如下: 1.将dll文件放入子文件夹 2.添加引用 解决方案资源管理器中,中 工程名或者“引用”上右键,选中添加引用. 中引用管理器中,点击浏览,选中子文件夹中的dll文件. 3.修改dll文件的引用属性 点击添加成功的引用,将“复制本地”改成false(不然程序运行的时候会将子文件夹下的dll文件复制到根目录中). 4.添加引用的地址,修改config文件 在根目录中打开“软件名.

初步学习Django-第三篇:URLS.PY文件详解

该文章转至博科:https://www.cnblogs.com/luchuangao/p/7113667.html urls.py:URL分发器(路由配置文件)URL配置(URLconf)就像是Django所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表.你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码.URL的加载是从配置文件中开始. 1.urlpatterns的两种形式: 没有前缀的情况,使用的列表(推荐方式)url

iOS开发过程中 xcode文件与Finder中文件保持一致 + 支付宝集成出错

目录 环境 前言 1.使用 Gem 安装 synx 2.直接在终端 Terminal 中开始使用 3.在使用的时候还可以加参数来实现不同的功能 4.解决项目中出现的一些 error 环境 OS X 10.11.1Xcode 7.1日期:2015/10/30 前言 最近公司项目要从 SVN 转到 Git,由于公司项目原先是由外包在2个月内赶工出来的,所以很多地方都不符合规范,就比如这次的重点——目录规范,外包的哥们的项目目录结构还算清晰,但在 Finder 中的目录结构就惨不忍睹了.这次的主角是 

【JSP中引入文件】JSP中获取根路径+引用js文件

在jsp界面中经常需要引入js.css等文件,通常都需要先获取项目根路径,然后再引入文件. 例如: 项目路径如下,需要在index.jsp中引入FusionCharts相关的js.css等: index.jsp <%@ page language="java" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.get

C#同一项目中不同文件或类中的方法进行调用

有两种方法,一是将被调用的类设置成静态类Static,这样就可以直接点出来了,二是将被调用的方法所在类设置成public,这几必须在调用类中先将被调用的类进行实体化,new()出来,再点出来. 一. public class A{ public void a(){}; } public class B{ public void b(){ A aa = new A(); aa.a(); } } 二. static class A{ public void a(){}; } static class

vue中入口文件mian.js中,使用elementUI中的组件this找不到指向。

错误使用: this.$message({ message: res.data.msg, type: 'error' }) 原因:mian.js中页面还未挂载完毕,使用this.$message()时,this指向了window,elementUI并未在window下注册该方法 解决方案: import Element from 'element-ui' Element.Message({ message: res.data.msg, type: 'error' }) 原文地址:https://

matlab读路径中的文件时路径中字母不区分大小写

load('D:\假期 motion blur\20160102\Image\LPQ\LPQ_BIO_Random1\Acc_Plot_P2');load('D:\假期 motion blur\20160102\Image\LPQ\lpq_BIO_Random1\Acc_Plot_P2');load('d:\假期 motion blur\20160102\Image\LPQ\lpq_BIO_Random1\Acc_Plot_P2');load('D:\假期 motion blur\2016010

mac idea中的文件在finder中打开

设置工具扩展: 原文地址:https://www.cnblogs.com/hoge66/p/8406354.html

Android中项目中各个文件夹的含义和用途详解

1.src:存放所有的*.java源程序. 2.gen:为ADT插件自动生成的代码文件保存路径,里面的R.java将保存所有的资源ID. 3.assets:可以存放项目一些较大的资源文件,例如:图片.音乐.字体等. 4.res:可以存放项目中所有的资源文件,例如:图片(*.png.*.jpg).文本等. 5.res/drawable-hdpi:保存高分辨率图片资源,可以使用Resources.getDrawable(id)可以获得资源类型. 6.res/drawable-ldpi:保存低分辩率图