参考教程:廖雪峰的JavaScript教程
文章目录
一、快速入门
1.1、数据类型和变量
1.双等号==
比较运算符会自动转换数据类型再比较,会得到很诡异的结果,所以不要使用双等号
2.三等号===
则不会自动转换数据类型,如果数据类型不一致,就直接返回false,如果一致,再进行比较。所以,不等号是一个感叹号加双等号:!==
3.NaN这个特殊的Number与其它所有值都不相等,包括它自己,唯一能判断NaN的方法是通过isNaN()
函数:
isNaN(NaN)这个表达式的值就算true
4.JavaScript的数组可以包括任意数据类型
1.2、字符串
1.字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是也不会有任何效果
2.如果要用${变量名}
的方式输出字符串,那应该用反引号’`'来把这个字符串给括起来,比如这样:
3.JSON.stringify()
方法能将一个JavaScript值/对象/数组转换为一个JSON字符串,比如下面就是一个JavaScript对象:
下面是一个json字符串:
1.3、数组
1.可以通过数组的索引把对应的元素改为新的值,这样可以直接修改这个数组(这和字符串是不一样的,字符串可以通过索引给某个位置赋新值,但是不会改变这个字符串)
2.concat可以把当前array和另一个array连接起来,并返回一个新的array。它还可以把array自动拆开,然后全部添加到新array里
1.4、条件判断
1.JavaScript把null,undefined,0,NaN和空字符串''
视为false,其它值一概视为true
1.5、iterable
1.array、map、set都属于iterable类型,它们都可以通过for...of
循环来遍历
2.iterable类型都有个内置的foreach方法,但是不同的iterable类型的foreach函数的参数不同:
1)Array:
var a=['A','B','C'];
a.forEach(function(element,index,array){
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
}
2)Set:
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
3)Map:
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
二、函数
2.1定义函数
1.js允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题。即使函数内部并不需要这些参数;甚至传入的参数比定义的少也没有问题
2.2箭头函数
(x,y,...rest)=>{
var i,sum=x+y;
for(i=0;i<rest.length;i++){
sum+=rest[i];
}
return sum;
}
这个箭头函数等价于
function(x,y,...rest){
var i,sum=x+y;
for(i=0;i<rest.length;i++){
sum+=rest[i];
}
return sum;
}
2.箭头函数相当于匿名函数,并且简化了函数定义
三、JSON
1.json的字符串规定必须用双引号" "
,Object的键也必须用双引号" "
四、websocket
这块我看廖雪峰的教程没太整明白,就先记录一下今天的收获吧
1.根据维基百科,websocket就是一种网络传输协议
2.要使用websocket,关键在于服务器端的支持,这样,我们才有可能用支持websocket的浏览器使用websocket
3.在node.js中,使用最广泛的websocket模块是ws
4.使用ws模块时,需要在package.json中添加ws的依赖:
5.使用websocket的前期工作就是,添加依赖+运行npm install
+创建app.js,然后就是在app.js里写代码
6.创建一个websocket的服务器实例过程:导入模块+应用Server类+实例化
// 导入WebSocket模块:
const WebSocket = require('ws');
// 引用Server类:
const WebSocketServer = WebSocket.Server;
// 实例化:
const wss = new WebSocketServer({
port: 3000
});
这样,我们就在3000端口上打开了一个WebSocket Server,这个实例通过变量wss引用
7.接下来,我们写一个connection事件,来处理可能发生的WebSocket请求接入:
wss.on('connection', function (ws) {
console.log(`[SERVER] connection()`);
ws.on('message', function (message) {
console.log(`[SERVER] Received: ${message}`);
ws.send(`ECHO: ${message}`, (err) => {
if (err) {
console.log(`[SERVER] error: ${err}`);
}
});
})
});
在上面的这个connection事件中,回调函数传入了websocket的实例,表示这个websocket连接。对于每个websocket连接,我们都要对它绑定某些事件和方法来处理不同的事件。在上面这段代码中,我们是通过相应message事件,在收到消息后再返回一个ECHO:xxx的消息给客户端
8.综合6和7,一个简单的服务器端WebSocket程序就编好了,如下:
//导入模块
const WebSocket=require('ws');
//引用server类
const WebSocketServer=WebSocket.Server;
//实例化
const wss=new WebSocketServer({
port:3000
});
wss.on('connection',function(ws){
console.log(`[SERVER] connection()`);
ws.on('message',function(message){
console.log(`[SERVER] received:${message}`);
ws.send(`ECHO:${message}`,(err)=>{
if(err){
console.log(`[SERVER] error: ${err}`);
}
})
})
});
现在有了服务器端的程序,现在我们需要通过客户端来创建WebSocket,然后给服务器发消息。这个,我们可以通过在浏览器中写JavaScript代码来实现。我们打开谷歌浏览器的开发者模式,在console中输入以下代码:
// 打开一个WebSocket:
var ws = new WebSocket('ws://localhost:3000/test');
// 响应onmessage事件:
ws.onmessage = function(msg) { console.log(msg); };
// 给服务器发送一个字符串:
ws.send('Hello!');
一切正常的话,可以看到Console的输出如下:
MessageEvent {isTrusted: true, data: "ECHO: Hello!", origin: "ws://localhost:3000", lastEventId: "", source: null…}
9.其实,ws模块既包含服务器端,又包含了客户端,所以我们也可以直接用ws模块提供的WebSocket来充当客户端。我们继续在app.js中输入以下代码:
//创建客户端
let ws = new WebSocket('ws://localhost:3000/test');
// 打开WebSocket连接后立刻发送一条消息:
ws.on('open', function () {
console.log(`[CLIENT] open()`);
ws.send('Hello!');
});
// 响应收到的消息:
ws.on('message', function (message) {
console.log(`[CLIENT] Received: ${message}`);
}
这段代码中的ws的类型和第7点的WebSocketServer相应connection事件时回调函数传入的变量ws的类型一致
10.我来根据自己的理解总结一下,就是我们可以通过在IDE中建项目、建websocketserver来建立服务器端,然后我们的项目就可以视为服务器端(虽然这样理解不正确,但这是我目前能理解的服务器和客户端的唯一方式了),浏览器就可以视为客户端;当然也可以通过在app.js里既写服务器端,又写客户端
11.浏览器创建WebSocket时发送的仍然是标准的HTTP请求,HTTP请求会被http.Server处理。具体的处理方式是由koa和WebSocketServer注入的回调函数实现的。WebSocketServer会首先判断请求是不是WS请求,如果是,它将直接处理该请求,如果不是,该请求仍由koa处理
12.关于识别用户身份,我们可以把用户登录后的身份写入Cookie。所以我们用WebSocketServer处理WS请求时,就可以根据Cookie识别用户身份
五、Koa2
5.1 koa入门
1.照例,先说一下koa是什么。根据koa官网的说法,koa是一个web框架。通过利用async函数,koa摒弃了回调函数,帮助开发者快速地编写服务端应用程序。
2.基于以下代码来分析一下
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
// 对于任何请求,app将调用该异步函数处理请求:
app.use(async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
});
// 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
3.对于每个HTTP请求,koa会调用我们传给app.use的async异步函数来处理,也就是下面这个:
async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
}
1)其中,参数ctx是由koa传入的封装了request和response的变量,我们可以通过这个参数访问request和response;next是koa传入的将要处理的下一个异步函数
2)由async标记的函数称为异步函数;在异步函数中,可以用await调用另一个异步函数
4.await next();
解释:koa把很多async函数组成一个处理链,每个async函数都可以自己做一些自己的事,然后用await next()来调用下一个async函数。在这里,每个async函数称为middleware,这些middleware可以组合起来起来完成很多功能。
5.在koa的处理链(第4点有提到)中,如果有一个async函数没有调用await next(),后面的middleware就将不再执行
5.2 处理URL
1.为了对不同的URL调用不同的处理函数,我们引入koa-router这个middleware来处理URL映射
2.具体引用和使用的过程:
//引入
const router=require('koa-router')();
//用router.get(...)注册get请求
router.get('/hello/:name',async(ctx,next)=>{
var name=ctx.params.name;
ctx.response.body=`<h1>hello,${name}</h1>`;
})
//最后记得用app.use调用这个middleware
app.use(router.routes());
koa-router相较于普通的koa().use(async(ctx,next)=>{...})
处理链的好处在于,不需要在每个async函数里通过分支和await next()
来完成不同url的处理:
app.use(async (ctx, next) => {
if (ctx.request.path === '/') {
ctx.response.body = 'index page';
} else {
await next();
}
});
app.use(async (ctx, next) => {
if (ctx.request.path === '/test') {
ctx.response.body = 'TEST page';
} else {
await next();
}
});
app.use(async (ctx, next) => {
if (ctx.request.path === '/error') {
ctx.response.body = 'ERROR page';
} else {
await next();
}
});
3.我们可以把url处理函数集中到某几个js文件中,然后让app.js自动导入所有处理url的函数。我们可以把提到的js文件放到controller文件夹中,类似下面的结构:
4.怎么把装到controller里面的处理函数给暴露出来呢?我们可以通过module.exports把这些处理函数暴露出来:
5.然后新建一个js文件,作为一个middleware,用于扫描处理函数和创建router
const fs = require('fs');
function addMapping(router, mapping){
for(var url in mapping){
if(url.startsWith('GET')){
var path=url.substring(4);
router.get(path,mapping[url]);
console.log(`register url mapping: get $ {path}`);
}else if(url.startsWith('POST ')){
var path = url.substring(5);
router.post(path,mapping[url]);
console.log(`register url mapping: post $ {path}`);
}else{
console.log(`invalid url: ${url}`);
}
}
}
function addControllers(router,dir){
var files = fs.readdirSync(__dirname+'/'+dir);
var js_files=files.filter((f)=>{
return f.endsWith('.js');
});
for(var f of js_files){
console.log(`process controller: ${f}...`);
let mapping = require(__dirname+'/'+dir+'/'+f);
addMapping(router,mapping);
}
}
module.exports=function(dir){
let
controllers_dir=dir||'controllers',
router=require('koa-router')();
addControllers(router,controllers_dir);
return router.routes();
}
6.最后在app.js中导入第5个点中提到的middleware并使用:
5.3使用Nunjucks
1.nunjucks是一个模板引擎,而模板引擎就是基于模板配合数据构造出字符串输出的一个组件,具体化就是一个函数
2.模板引擎的使用:
function render(view,model){
//do something...
}
其中,view是模板的名称(又称为视图);model就是数据,在js中,他就是一个简单的object;render函数会返回一个字符串,就是模板的输出
3.在HTML文件中,如果出现{% … %}的字样,这是模板引擎的语法,比如:
<html><body>
{% block header %} <h3>Unnamed</h3> {% endblock %}
{% block body %} <div>No body</div> {% endblock %}
{% block footer %} <div>copyright</div> {% endblock %}
</body>
{% block header %} <h3>Unnamed</h3> {% endblock %}
就表示是模板中的header块
5.4 MVC
1.MVC:model-view-controller,模型-视图-控制器
2.View负责显示逻辑,通过简单地替换一些变量,view的输出就是用户看到的HTML
3.controller负责业务逻辑,比如检查用户名是否存在,取出用户信息等
4.model就是用来传给view的,这样view在替换变量时,就可以从model中取出相应的数据。最简单的时候,model甚至可以是一个js对象:{name:'michael'}
5.所谓的production环境,就是正式环境,即应用的线上环境。node.js在全局变量process中定义了一个环境变量env.NODE_ENV,我们在开发时,环境变量应该设置为’development’,而部署到服务器时,环境变量应该设置为’production’
六、node
1.运行app.js有以下3种方式:
1)在IDE中点击运行(这个不用IDE有不同的方式)
2)用npm start
启动
3)在命令行中用node app.js
启动程序
七、socket.io
1.socket.io由两部分组成:
1)一个服务端用于集成(或挂载)到node.js HTTP服务器:socket.io
2)一个加载到浏览器中的客户端:socket.io-client
2.socket的定义就是,每次访问一个地址,就相当于一个新的用户
3.socket.emit(…)向服务器端发送一个事件,具体可看官方的几个示例:
io.on('connection', function(socket){
socket.emit('request', /* */); // emit an event to the socket
io.emit('broadcast', /* */); // emit an event to all connected sockets
socket.on('reply', function(){ /* */ }); // listen to the event
});
八、jQuery
1.$('#m').val('');
//$是一个选择器;val是返回这个#m的值
2.jquery的作用就是通过选中标签来绑定函数
最后、其它零碎知识
1.$(function() {})
:它是一个jQuery函数,当文档载入完成时执行的
参考链接:https://blog.csdn.net/dongdong9223/article/details/50504518