# 前端爱好者学习周刊:第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())
})
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())
}
})
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())
}
})
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)
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
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)
}
}
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
2
3
4
5
6
7
8
9
10
应该使用function的形式
Person.prototype.sayName = function(){
console.log(this === window) //true
return this.pName
}
2
3
4
# 3).动态上下文中的回调函数
箭头函数的this是在声明时就绑定好的,所以不再动态变化;
dom元素上绑定监听函数:
var btn = document.getElementById('btn')
btn.addEventListener('click', () => {
console.log(this === window) // true
this.innerHTML = 'clicked button' // btn上没有变化
})
2
3
4
5
6
应该使用function表达式:
btn.addEventListener('click', function(){
console.log(this === window) // false
this.innerHTML = 'clicked button' // btn上文字变化
})
2
3
4
# 4).构造函数
var Person = (name) => {
this.name = name;
}
// Uncaught TypeError: Person is not a constructor
var person = new Person('www')
2
3
4
5
6
var Person = function(){
this.name = name;
}
2
3
# 驼峰与连字符的互转
驼峰转连字符:
//正则中的$1表示第一个括号匹配到的
var s = "fooStyleCss";
s = s.replace(/([A-Z])/g,"-$1").toLowerCase();
2
3
连字符转驼峰:
var s1 = "foo-style-css";
s1 = s1.replace(/-(\w)/g, function(x,y){
console.log(x,y)
return y.toUpperCase();
});
2
3
4
5
6
# 补充[replace]
stringObject.replace(regexp/substr,replacement)
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
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(获取数据),或者直接返回状态码
- 系统分层
- 可缓存
- 按需编码、可定制代码(可选)