# 前端爱好者学习周刊:第7期

20191222

# Node fs模块、readFile、readFileSync方法

  • fs模块——node.js自带的文件系统

  • 写法:var fs = require('fs')

  • 文件系统方法分为:同步,异步

    • 异步:最后一个参数为回调函数,回调函数的第一个参数为错误信息(错误优先)
  • 异步性能高,速度快,没有阻塞,推荐。

# readFile

  • 用法:错误优先机制,回调函数的第一个参数为错误信息
fs.readFile('houdun.txt',function(err,data){
	if(err){
		console.error(err)
	}
	console.log('异步读取:'+data.toString())
})
1
2
3
4
5
6
  • 其中data获得的是文件内容的buffer(二进制)数据,想获得原字符串内容就要加toString()方法
var fs = require('fs')
fs.readFile('./02.js',(err,data) => {
	if(err){
		console.log('出错了',err)
	} else {
		console.log('data,data.toString())
	}
})
1
2
3
4
5
6
7
8

# readFileSync()方法

  • readFile()是异步的方法
fs.readFile('./hd.txt',(err,data) => {
	if(err){
		console.log('出错了',err)
	} else {
		console.log('data,data.toString())
	}
})
1
2
3
4
5
6
7
  • readFileSync()方法是其同步方法的版本,会产生阻塞效果
const fs = require('fs')

console.log(1)

const data = fs.readFileSync('./02.js')
console.log(data.toString())

console.log(2)

1
2
3
4
5
6
7
8
9

结果为: 1 同步读取文件 2

# 什么时候不该使用=>

什么时候不该使用es6箭头函数 (opens new window)

# 1).在对象上定义函数用到this

由于箭头函数的this是外围作用域的,所以在调用对象时,会取外层this,箭头函数中用到this就会报错;

 const obj = {
    array:[1,2,3,4],
    sum:() => {
        console.log('this===window',this===window); // true
        return this.array.reduce((res,item) => res + item)
    }
}
obj.sum()

// Uncaught TypeError: Cannot read property 'reduce' of undefined
1
2
3
4
5
6
7
8
9
10

应该使用es6简写函数属性的写法:

const obj = {
    array:[1,2,3,4],
    sum(){
        console.log('this===window',this===window); // true
        return this.array.reduce((res,item) => res + item)
    }
}
1
2
3
4
5
6
7

# 2).在原型上定义函数用到this

function Person(pName){
    this.pName = pName
}

Person.prototype.sayName = () => {
    console.log(this === window) //true
    return this.pName
}
var person = new Person('wdg')
person.sayName() // undefined
1
2
3
4
5
6
7
8
9
10

应该使用function的形式

Person.prototype.sayName = function(){
    console.log(this === window) //true
    return this.pName
}
1
2
3
4

# 3).动态上下文中的回调函数

箭头函数的this是在声明时就绑定好的,所以不再动态变化;

dom元素上绑定监听函数:

var btn = document.getElementById('btn')
    
btn.addEventListener('click', () => {
    console.log(this === window) // true 
    this.innerHTML = 'clicked button' // btn上没有变化
})
1
2
3
4
5
6

应该使用function表达式:

 btn.addEventListener('click', function(){
    console.log(this === window) // false
    this.innerHTML = 'clicked button' // btn上文字变化
})
1
2
3
4

# 4).构造函数

var Person = (name) => {
    this.name = name;
}

// Uncaught TypeError: Person is not a constructor
var person = new Person('www')
1
2
3
4
5
6
var Person = function(){
    this.name = name;
}
1
2
3

# 驼峰与连字符的互转

驼峰转连字符:

//正则中的$1表示第一个括号匹配到的
var s = "fooStyleCss";
s = s.replace(/([A-Z])/g,"-$1").toLowerCase();
1
2
3

连字符转驼峰:

var s1 = "foo-style-css";
s1 = s1.replace(/-(\w)/g, function(x,y){
    console.log(x,y)
    return y.toUpperCase();
});

1
2
3
4
5
6

# 补充[replace]

stringObject.replace(regexp/substr,replacement)
1

replacement:

  • 字符串

    • 一般字符串
    • $特殊处:

    $1、$2、...、$99: 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。

    $& 与 regexp 相匹配的子串。

    $` 位于匹配子串左侧的文本。

    $' 位于匹配子串右侧的文本。

    $$ 直接量符号。

  • 函数

    • 参数:
     (
    	匹配模式的字符串, 
    	0 个或多个这样的与模式中的子表达式匹配的字符串,
    	声明匹配在 stringObject 中出现的位置,
    	stringObject 本身
    )
    
    1
    2
    3
    4
    5
    6

var name = 'aaa bbb ccc';

var uw=name.replace(/\b\w+\b/g, function(word){
    console.log(word)
    return word.substring(0,1).toUpperCase()+word.substring(1);}
);

console.log(uw); //Aaa Bbb Ccc

1
2
3
4
5
6
7
8
9

# Restful了解

Representational State Transfer

如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构

REST全称是表述性状态转移,其实指的就是资源;任何事物,只要有被引用到的必要,它就是一个资源

要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。

URI的设计应该遵循可寻址性原则,具有自描述性,需要在形式上给人以直觉上的关联

URI设计上的一些技巧:

  • 使用_或-来让URI可读性更好
  • 使用/来表示资源的层级关系
  • 使用?用来过滤资源
  • ,或;可以用来表示同级资源的关系

Rest架构的主要原则:

  • 网络上的所有事物都被抽象为资源

  • 每个资源都有一个唯一的资源标识符

  • 同一个资源具有多种表现形式(xml,json等)

  • 对资源的各种操作不会改变资源标识符

  • 所有的操作都是无状态的


RESTful架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。

如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如GET和HEAD请求都是安全的, 无论请求多少次,都不会改变服务器状态。

采用HTTP协议规定的GET、POST、PUT、DELETE动作处理资源的增删该查操作:

method ---- descprition
POST Create 在服务器新建一个资源
GET Read 从服务器取出资源(一项或多项)
PUT Update 在服务器更新资源(客户端提供完整资源数据)
DELETE Delete 从服务器删除资源
  • 如何给老婆解释什么是RESTful (opens new window):通俗易懂的一篇讲解

    • Restful的第一个特征——面向资源
    • 与面向资源的RESTful不同的SOAP的特点是关注行为和处理
    • HTTP作了一种传输协议
    • HTTP动词;GET/PUT/POST/DELETE/PATCH....,这些都是HTTP的规范
    • 幂等(POST)-调用要小心;不是幂等的(PUT,GET),调用多少次都没事
    • HATEOAS(Hypertext As The Engine Of Application State),中文翻译为“将超媒体格式作为应用状态的引擎”,核心思想就是每个资源都有它的状态,不同状态下,可对它进行的操作不一样
    • 只需要知道如何获取资源的入口,之后的每个URI都可以通过请求获得,无法获得就说明无法执行那个请求。
    • Restful对数据格式没有限制,就算你用的是XML或者其他格式,只要符合上面提到的几个特征,也算Restful
    • (作者确实说的对,目前大多数都做到了level2,少见到添加link,做到“完美服务的”)
  • 理解RESTful架构 (opens new window)

    • 网站即软件;
    • 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点
    • 现在我们必须考虑,如何开发在互联网环境中使用的软件。(网站开发,软件开发)
    • RESTful架构,就是目前最流行的一种互联网软件架构
    • 资源",就是网络上的一个实体,或者说是网络上的一个具体信息;可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI;URI就成了每一个资源的地址或独一无二的识别符
    • 所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI。
    • "资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)
    • 互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
  • RESTful API 设计指南 (opens new window)

    • 在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应
      • GET /zoos:列出所有动物园
      • POST /zoos:新建一个动物园
      • GET /zoos/ID:获取某个指定动物园的信息
      • PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
      • PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
      • DELETE /zoos/ID:删除某个动物园 GET /zoos/ID/animals:列出某个指定动物园的所有动物
      • DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
    • RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
    • (这篇后台web开发建议好好看一下这篇文章)
  • 面试官:你连RESTful都不知道我怎么敢要你? (opens new window) RESTful6大原则:

    • C-S架构:Server端存数据,Client端使用;互相独立,互不干扰
    • 无状态:http请求本身就是无状态的,由客户端带各种信息参数去请求,无状态的特征提高了服务端的健壮性和可拓展性。
    • 统一的接口
    • 一致的数据格式:服务端返回的数据格式要么是XML,要么是Json(获取数据),或者直接返回状态码
    • 系统分层
    • 可缓存
    • 按需编码、可定制代码(可选)