yzl的javascript学习笔记

参考教程:廖雪峰的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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值