JavaScript学习总结

102 阅读21分钟

JS学习总结第五周

周一

1、保护对象:保护对象的属性和方法

1、每个属性都有四大特性:
  {
    value: '很多', //实际保存值的地方
    writable: true, //开关,控制着这个属性是否可以被修改 - 默认值为true
    enumerable: true, //开关,控制着这个属性是否可以被for in循环遍历到 - 默认值为true
    configurable: true //开关,控制着这个属性是否可以被删除 - 默认值为true,总开关:一旦设置为
    false,其他特性不可以再修改,而且他本身也是一旦设置为false,不可逆
}

	修改四大特性:
		1Object.defineProperty(对象名,"属性名",{
				四大特性
			})

			调用一次方法只能保护一个属性的四大特性

		2Object.defineProperties(对象名,{
				"属性名":{四大特性},
				...
			})

			至少方法只调用了一次,但是四大特性写着始终麻烦,甚至不能防止添加

2、三个级别:
		//1、防扩展:防添加
		Object.preventExtensions(obj);

		//2、密封:防添加防删除
		Object.seal(obj);

		//3、冻结:防添加防删除防修改
		Object.freeze(obj);

保护对象不重要:为什么说他垃圾?
	1、如果你不用面向对象开发,那你也没有对象可以保护
	2、前辈们都没有保护,我们也不用保护
	3、别人一般来说都不可能知道你取得对象名字叫什么

***四大特性,其实应该叫六大特性 - 可以帮助我们做出动态数据,以后不会手动使用,只是明白Vue底层就是用到了set拦截操作
		Object.defineProperty(lhl,"name",{
			get:()=>{
				console.log("获取数据会进行拦截操作");
			},
			set:v=>{
				console.log("设置数据会进行拦截操作"+v);//v拦截到的数据
				h1.innerHTML=v;
			},
		})

2、*对象的深浅拷贝:

1、浅拷贝:利用按值传递
   var obj1={"name":"obj1"};
   var obj2=obj1;

2、深拷贝:两者互不影响
	var obj1={"name":"obj1"};
	var obj2={...obj1};

3、*以后如何脱掉后传来的数据的衣服:
	后端穿衣服:var JSONtxt=JSON.stringify(obj); - Node.js就是这句话,Node.js也是“js”,历史上第一次一门语言可以通吃前后端
	前端脱衣服:var jsonObj=JSON.parse(JSONtxt);
	此方法也能实现深拷贝

3、*Error对象:错误

1、以后工作/学习的目的:
    1、快速找到错误
    2、记住要防用户

2、***浏览器自带4种错误类型:可以快速找到自己的错误
	1、语法错误:SyntaxError - 一定是你的符号/语法写错
	2、引用错误:ReferenceError - 没有创建就去使用了
	3、类型错误:TypeError - 不是你的方法,你却去使用了
	4、范围错误:RangeError - 只有一个API会碰到:num.toFixed(d);//d取值范围:0~100之间

3、只要发生错误,就会报错,会导致后续代码终止(闪退),我们不希望
	错误处理:就算发生错误,我们也不希望报错,而是给出一个错误提示,让后续代码依然可以继续执行!
	语法:
		try{
			只放入你可能出错的代码
		}catch(err){
			发生错误后才会执行的代码
			err形参就保存着错误的消息,只不过是英文的,中国人不一定看得懂,所以建议你添加上中文的错误提示
		}
	try...catch...的性能非常的差,几乎事所有代码里性能最差的,放在try中的代码效率都会被降到最低
	*可以用一个技术代替他:分支技术!
	*开发经验的累计:记住一切的客户端输入/用户输入都是坏人 - 但是你不担心,只要你做还要防护就不会出错(!isNaN、正则)

4、抛出自定义错误:只要是错误,后续代码都不会执行
	throw new Error("自定义错误消息")

5ES5:严格模式
	开启:"use strict" - 写在任何一个作用域的顶部都可以
	作用:
		1、禁止了全局污染,使用变量之前必须先创建变量
		2、将静默失败升级为报错
	铺垫:以后我们用了gulp技术打包项目后,有的js会自动加上严格模式,我劝你把他删掉

4、柯里化函数:

function add(a){
    return function(b){
      return function(c){
         console.log(a+b+c)
    }
  }
}

add(3)(5)(7);

周二

1、*匿名函数:没有名字的函数,有两种用法:

1、自调:只能执行一次,好处:函数中的没有用的变量是会自动释放的,它可以用于代替全局代码写法,两者
   很相似,都只会执行一次,但是自调会释放没用的东西
   (function(){
     操作;
    })();

2、回调:匿名函数不是自调,就是回调,所以回调函数,我们往往只需要学习如何使用即可
	elem.on事件名=function(){}
	arr.sort(function(){})
	xxx.api(function(){})
	var obj={
		"方法名":function(){}
	}
	一切的回调函数,都可以简化为箭头函数

2、设计模式:不仅仅局限于前端,它是一种编程【思想】,越来越复杂,对于我们前端人来要求也会越来越高!

1、单例模式:也称之为单体模式,保证一个类仅有一个实例对象创建,并且提供一个访问它的全局访问点:为了
三阶段的Vue做准备:new Vue一个页面只写一次/一个!

如何实现:
	最简单的单例模式:利用ES6let不允许重复声明的特性,刚好就符合了单例的特点:
		let obj={
			"name":"袍哥1",
			"getName":function(){return this.name},
		}
	不太推荐这种写法:
		1、污染命名空间(容易变量名冲突,会报错)
		2、维护时不易管控(搞不好就直接覆盖了)

	推荐写法:
	var h52302=(function(){
		let state=null;
		return function(name,age){
			this.name=name;
			this.age=age;
			if(state){
				return state;
			}
			return state=this;
		}
	})();
	
	h52302.prototype.sayHello=function(){
		console.log(this.name);
	}
	
	var x=new h52302("xxx",18);
	var y=new h52302("yyy",19);
	
	console.log(x);
	x.sayHello();
	
	console.log(y);
	y.sayHello();
		
2、观察者模式:也有人称呼叫做发布订阅模式:为三阶段vue的bus总监用到的底层原理就是我们的发布订阅模式
现实举例:QQ空间,朋友圈,微博...
	let obj={};
	
	//创建订阅者
	function on(id,fn){
		if(!obj[id]){//判断有没有此id(有没有这个人),没有我就创建了一个空数组
			obj[id]=[];
		}
		obj[id].push(fn);//obj["袍哥"]=[(msg)=>{console.log("小胡来了",msg)},(msg)=>
                    {console.log("小罗来了",msg)},(msg)=>{console.log("小向来了",msg)}]
	}
	
	on("xx",(msg)=>{console.log("小胡来了",msg)})
	on("xx",(msg)=>{console.log("小罗来了",msg)})
	on("xx",(msg)=>{console.log("小向来了",msg)})
	on("xx",(msg)=>{console.log("小张来了",msg)})
	on("xx",(msg)=>{console.log("小王来了",msg)})
	on("xx",(msg)=>{console.log("小李来了",msg)})
	
	//发布者的操作
	function emit(id,msg){
		obj[id].forEach(fn=>fn(msg));//obj["袍哥"].forEach(fn=>fn("一支穿云箭"))
	}
	
	btn.onclick=()=>{
		emit("xx","一支穿云箭");
	}

3、*事件轮询:js其实是单线程应用,代码必须是从上向下执行的,一步一步执行的,如果某一块代码非常耗时,可能会导致整个页面都卡住了,尤其如果你把js放在head之中,会看到页面是一个白板!

1、宏任务:不会再卡住我们的单线程应用,可以让后续代码先走,我们慢慢跟着来,但是问题在于,多个宏任务
   同时存在,到底谁先执行,谁后执行,分不清楚
    1、定时器:setIntervalsetTimeout()
    2AJAX2、微任务:ES6提供了Promise对象 - 可以控制异步代码,依然是异步代码,但是可以控制执行的顺序了
		function ajax1(resolve){
			setTimeout(()=>{
				console.log(1);
				resolve();//放行函数
			},Math.random()*5000)
		}
		function ajax2(){
			return new Promise(resolve=>{
				setTimeout(()=>{
					console.log(2);
					resolve();
				},Math.random()*5000)
			})
		}
		function ajax3(){
			return new Promise(resolve=>{
				setTimeout(()=>{
					console.log(3);
					resolve();
				},Math.random()*5000)
			})
		}
		new Promise(ajax1).then(ajax2).then(ajax3);
		console.log("后续代码");

html5十大新特性:不单单只是由标签组成。h5其实是一个综合概念

1、新的语义标签(nav header section article aside footer2、增强性表单(表单2.0);
3、音频和视频(audiovideo4Canvas绘图 - 统计图,以前18年的大纲里有它,后来淘汰了(不是他不行,是你们不行,你画出来会很丑),
   我们数据可视化使用echart.js
5、Svg绘图 - 小图标
6、地图 - 百度/高德
7、拖放API事件
8、web worker
9、web storage
10、web socket

周三

	可能成为全栈的语言:
		1、Java语言 - 里面有JavaWeb,但是不包含移动端(安卓)
		2、JavaScript语言:
			客户端 - 开发根本
			服务器端 - Node.js 历史第一次一门语言可以通吃前后端(前端崛起的原因之一)
			数据库 - mongoDB
			移动端 - 网页/app(跨所有平台的:IOS/Andriod)/小程序/公众号

			前端崛起的原因之一:三阶段你会学习混合开发框架:jQueryMobile/h5+plus/【uniapp】
                    - 只需要一个前端学一点点IOS/Andriod的语法就可以搞定了
			前端的崛起导致IOS/Andriod开发者大量的失业:千万不能啃老本

1、基本内容:

服务器端概念:
简单来说就是一台电脑
生活中:微机
商业中/国家用:小型机(造价大概几十万好的上百万) + 中型机 + 大型机 + 超级计算机

拥有服务器的方式:
	1、买 - 对中小型公司不友好
	2、买一台配置好一点的微机 - 对于别的行业的公司也不太划算
	3、租云服务器 - 腾讯云、阿里云、新浪云、百度云...配置咨询,配置越好,价格越高,按年收费

软件架构:服务器端很重要
C/S架构 - Client客户端/Server服务器端
	举例:QQ、微信、大型网络游戏

	优点:
		1、用户体验感较好
		2、运行稳定
		3、对带宽的要求低
	缺点:
		1、占硬盘空间
		2、更新过于麻烦 - 服务器端和客户端都要更新

B/S架构 - Browser浏览器端/Server服务器端
	举例:网页版QQ、网页版微信、网页游戏

	优点:
		1、几乎不占用硬盘
		2、更新简单 - 只需要更服务器端
		3、电脑在垃圾都可以玩得起!- 不吃配置,代码都在服务器那边运行
	缺陷:
		1、用户的体验感较差(越来越好,尤其是现在出现了云平台,根本不用考虑你的电脑好不好,配置
             如何)
		2、对于带宽的要求高(还好现在的网速越来越快的)。

3、Node.js概述:不是JS,但是语法和JavaScript非常相似,他的竞争对手:Java、C++、C#、python、PHP...

功能绝对不是做特效的!做的事和服务器端其他语言是一致(和数据库进行交互,成为了一个前端到数据库的中间
桥梁)
目的:
   1、使用代码搭建一个服务器&文件系统(服务器文件可以放在任何位置,但是不在你的电脑里,你也可以根据
      网址来访问我的东西)
   2、Node.js如何沟通前端和数据库(增删改查)
   3、全栈项目:图书管理系统(HTML+CSS+JS+NODE+MONGO)

   4、Node.js如何运行:3种
       1、交互模式 - 临时测试
          打开cmd输入:node回车,你就可以开始敲你的“js”代码

       2、脚本/文件模式 - 正式开发中
	         1、先创建xx.js,里面书写自己的代码
	         2、打开cmd输入:node 文件的绝对路径

             3、编辑器越来越强大了,安装插件:前提:至少前两个方法能够成功,才可以安装插件
	              vscode - 插件:code runner,对着代码处右键,第一个选项就是code runner,或者右上角
                  有一个开始按钮可以点击,有的同学(输出会乱码,可以百度找解决方案)

4、Node.js知识:

1、js和node的区别
   相同点:都可以使用一切的ECMAScript(那11个)的东西,包含一切的API,都可以使用,在服务器端不存在
           任何浏览器,所以不必担心兼容问题
   不同点:
        1JavaScriptES+BOM+DOM - 做特效的
        2Node.js:一切的BOMDOM都没有,虽然没有BOMDOM,但是他却又10万+个以上的模块等待我们学习

2、模块(module):每一个xx.js,都可以称之为是一个模块
       1、模块化开发:如果以一个网站来说,我们可以按功能分为很多模块:商家模块、商品模块、促销模块、
           用户模块、产品模块....
	       分工合作:将每个模块交给对应的人完成,最后再由【主模块】进行引入:
	
	      2、每一个模块都有一个操作,可以用于公开/暴露自己的成员
		Node.js自带一个预定义变量:exports,可以直接使用,是一个对象,放在此对象里面的东西,就是
          允许公开的东西
		语法:
			1exports.属性名=值;
			2module.exports.属性名=值;
			3module.exports={
				属性名:属性值,
				...
			      }

			错误导出法:
				exports={
					"name":"袍哥1",
					"age":18,
					hobby:"吃饭"
				};

	      3、每一个模块(主模块)都有一个操作,可以用于引入/导入其他模块
		Node.js自带一个预定义变量:require,可以直接使用,是一个函数,放在此函数里面的路径,就是
                    允许引入的模块文件
		语法:
			var x=require("./路径");

	面试笔试题:exportsmodule.exports有什么区别?
		1、语法、写法,用法不同
		2、都是用于公开暴露自己的成员的
			但是exports={},写法是错误的
			其实Node.js底层有一句话:exports={}
			其实真正做公开功能的是module.exports
			如果你使用了	            exports={};//你创建了一个新的空对象,把module.exports覆盖了,
                            所以不再具有公开的功能	

3、模块的分类:
	1、官方模块 - 今日的目标,大概有二十几个,但是重要的其实只有几个
	2、第三方模块 - 在npm上放着的,多到数不清楚,提供了很多官方没有的东西,明天我在学习,可以上传也可以去下载
	3、自定义模块

	Node.js最大的特点:
		1、快,非常快 - 以前最快的是php,js的速度是php的十六倍
		2、为什么这么快
			1、因为官方模块提供的东西少,甚至连操作数据的API都没有提供过
			2、使用chrome浏览器的v8引擎

4、官方模块:不需要下载,在你安装node.js环境的时候就已经带上了,但是某的模块需要
    引入,某的模块不需要引入
	1Global模块:不需要引入的,可以直接使用
		提供了:
			1、五个预定义变量,可以直接使用了
				1、__filename - 获取到当前文件完整的绝对路径
				2、*__dirname - 获取当前文件绝对路径,不包含文件的名字,何时:vscode的
                                    某些同学可能不支持node.js上书写相对路径,只能书写绝对路径,但是
                                    绝对路径全由自己写又很累,有了此变量我们可以直接拼接!
                                    - 【文件系统】!
				3、*exports - 空对象,可以用于公开暴露自己的成员
				4、*require - 函数,可以用于导入其他模块
				5、***module - 指代当前模块本身,甚至包含着以上4个操作
			2、定时器(周期性、一次性、瞬间定时器):定时器不是当初
                            的定时器,只不过用法和当初一模一样!
			3console也不是当初的console,只不过用法和当初一模一样!

	2、querystring模块:解析查询字符串,使其变成一个对象,可以获取到前端传到后端
          的消息(前端传到后端的消息-请求消息)
		需要引入:var qs = require('querystring');
		作用:解析url中查询字符串部分的功能
		var obj=qs.parse("查询字符串");
		想要获得前端传来的每一个部分:obj.键名;
		垃圾:如果前端传来的是一个完整的url网址,他就解析不了

	3、***url模块 - 今日小重点
		需要引入:var url = require('url');
		作用:解析url中各个部分的功能
		var objUrl=url.parse("完整的url",true);//支持第二个参数,是一个布尔值,默认为false,一旦
                    设置为true,就会自动使用querystring的parse方法去解析查询字符串部分
		***真正的重点:
			1、查询字符串/请求消息:objUrl.query.键名; - 前端form(GET)表单提交到后端的东西
			2、路由/文件相对路径/请求地址:objUrl.pathname - 判断路由的不同,去读取不同的
                            HTML发送给我们的用户看!

	4Buffer模块:缓冲区,可以将数据变成一个16禁止的数字,你可以理解为是Node.js中的一种新的数据类型,
            但是我们绝对不会手动使用,因为我们一眼看不懂!
		  但是后端的一些API可能会导致我们被动得到Buffer,但是你也别怕,因为Node.js中大部分
             API,都是支持Buffer

	5、*****fs模块 - 今日大重点:fileSystem文件系统
		需要引入:var fs = require('fs');
		*异步读取文件:
			fs.readFile(文件路径,(err,buf)=>{
				console.log(buf);->读取到了要干什么,必须放在这个回调函数里面!
			})

		异步写入文件:
			fs.writeFile(文件路径,"新内容"/buf,(err)=>{
				console.log("写入完毕后要做什么,必须放在里面")
			})//会替换掉原来的东西

		异步追加文件:
			fs.appendFile(文件路径,"新内容"/buf,(err)=>{
				console.log("写入完毕后要做什么,必须放在里面")
			})//不会替换掉原来的东西

		强调:只有异步才能更完美的发挥Node.js的特点(快)

周四

1、Node.js官方模块:

6、http模块 - 超级重点:搭建服务器&文件系统
    var http=require("http");
    var url=require("url");
    var fs=require("fs");
    
    //创建服务器应用
    var app=http.createServer();
    
    //为其绑定端口号
    app.listen(80);
    
    //为其绑定了请求事件:http:请求 - 响应模型,必须要有一个请求(前端),才有一个响应(后端)
    app.on("request",(req,res)=>{//只要有人来请求,我就会触发
    
   //req:request(请求)对象,他有一个属性叫做req.url,获取到前端传到后端的路由和请求消息,但是路由
   和请求消息是融为一体,不方便我们获取某个部分,所以我们可以引入url,进行解析!分开两部分
   
   var objUrl=url.parse(req.url,true);
   //把路由保存了起来!
   var router=objUrl.pathname;
   
   if(router=="/"||router=="/index.html"){//判断路由的不同,读取不同的页面给用户看,引入fs文件模块
   //res: response(响应)对象,他有一个方法叫做res.end("响应的内容"/buf) - 可以想应该给前端想要
   看的东西
   fs.readFile(__dirname+"/public/html/index.html",(err,buf)=>{
         res.end(buf)
    })
  }else if(router.match(/html/)!=null){
     fs.readFile(__dirname+`/public/html${router}`,(err,buf)=>{
          res.end(buf)
  })
 }else if(router.match(/css|js|jpg|png|gif|woff|woff2|ttf2/)!=null){
    fs.readFile(__dirname+`/public${router}`,(err,buf)=>{
       res.end(buf)
   })
  }
})

扩展:字符串有一个API:match

var rs=str.match(reg);//几乎和indexOf一致,但是支持正则,我们不关心为什么,只关心为不为null 
强调:一切的src和href都是一个请求都是一个路由,这个请求就需要后端来解析,根据不同的请求响应不同的
      内容!


为什么有的模块引入要./有的又不用./?
	自定义模块:分为两大类
		1、文件模块:创建xx.js去公开了需要公开的内容,主模块引入,就必须写为require("./模块路径");

		2、目录模块:31、比如创建m1的文件夹,在其中创建index.js的文件,去公开了需要公开的内容,主模块引入,
                    就必须写为require("./m1");
			2、比如创建m2的文件夹,在其中创建suibian.js的文件,去公开了需要公开的内容,主模块
                     引入,就必须写为require("./m2");
				必须在创建一个必须名package.json的配置文件,写入:{"main":"suibian.js"}
			3、创建一个文件夹必须名为node_modules,在在其中创建创建m3的文件夹,在其中创建
                     index.js的文件,去公开了需要公开的内容,主模块引入,就必须写为require("m3");
		
		其实真实开发中,我们程序员用的最多的就是文件模块,目录模块的第三种方式其实根本不是给人用
           的(第三方模块下载后会自动创建此文件夹)

3、如何下载第三方模块:

npm工具:Node Package Manager - Node.js的模块/包/软件管理器,专门用于管理第三方模块的,
作用:下载、更新、删除、维护包之间的依赖关系
检查npm是否安装成功:npm -v 如果能看到版本号,说明安装成功
打开网址:npm官网:[www.npmjs.com](http://www.npmjs.com)
搜索你需要用到的模块,尽量用带有完全符合标签的那个包,或者是 第一个包
在你的项目之中打开cmd
    1、下载:npm i 包名
    2、删除:npm un 包名
    3、更新:npm up 包名

周五

mongo就是基于json的数据库:json就是JavaScript Object Notation - JS的一部分,所以用法和JS的用法都很像,都是用.去做操作

1、安装&启动:

1、解压我提供的mongodb-win32-x86\_64-2008plus-ssl-3.6.11.zip文件
2、打开bin文件夹,里面有:mongo.exe(客户端) 和 mongod.exe(服务器端)
3、如何启动:
        在bin文件夹中打开cmd:输入:.\mongod.exe --dbpath=你想要保存的绝对文件夹路径 - 服务器开启
        成功,而且那个文件夹就是保存着你以后要存储的所有的数据
   千万不要关闭mongo服务器端的cmd
   再打开一个cmd:输入:.\mongo.exe - 再上一个cmd可以查看我们是否连接成功 - 客户端开启成功

2、mongo的语法:都是在客户端cmd输入

1、数据库的操作
    1、查询所有数据库:show dbs
    2、创建/切割数据库:没有就创建,有了就切换:use 数据库名称
    3、查看当前选中的数据库:db
    4、创建数据表:db.createCollection("表名");- 没有限制,无限,一定要先创建数据表后,我们才能
       查看到自己创建的数据库
    5、删除数据库:db.dropDatabase(); - 一旦删除就不能恢复,不推荐,因为要坐牢,最好忘记

2、数据表的操作
	1、创建数据表:db.createCollection("表名",{size:5242880,capped:true,max:5000}); - 最大
     存储空间为5mb,最多存储5000个,意味着这个数据表做了限制,不推荐
	2、查看目前所有的数据表:db.getCollectionNames();
	3、删除数据表:db.表名.drop(); - 一旦删除就不能恢复,不推荐

3、*****数据的操作
	1、增:db.表名.save({键值对,...}) - 一次只能插入一条数据
		db.表名.save([{},{},{},{},....]) - 一次插入多条数据
		举例:db.user.save({name:"paoge",pwd:"123123",age:18,email:"pg@qq.com",vip:1})
		          db.user.save([{name:"hujiayuan",pwd:"333333",age:17,email:"hjy@qq.com",vip:0},
                      {name:"luohongliang",pwd:"666666",age:16,email:"lhl@qq.com",vip:0},
                      {name:"zhaoxiao",pwd:"999999",age:64,email:"zx@qq.com",vip:1}])

	2、删:db.表名.remove({}) - 不推荐,删除数据库中所有的数据
		db.表名.remove({条件}) - 条件依然也是键值对,比如: db.user.remove({name:"paoge1"}) - 
            会删除数据表中name叫做paoge1的所有数据

	3、改:db.表名.update({条件},{$set:{新内容}})
		举例:db.user.update({name:"zhaoxiao"},{$set:{age:65,pwd:"222222"}})

	4、查:db.表名.find(); - 找所有
		db.表名.find({pwd:"666666"}); - 找到所有密码为666666的数据
		db.表名.find({},{name:1,pwd:1}); - 找到所有的数据,但是只返回name和pwd(登录!)
		db.表名.find().sort({age:1}); - 按age升序排列!
		db.表名.find({age:{$gte:18}}) - 拿到所有age大于等于18的数据,gt大于 gte大于等于 lt小于  
            lte小于等于(获取成年人)
		db.表名.find({name:/o/}) - 甚至可以用正则(模糊查询)
		db.表名.find().skip(5).limit(5) - 跳过前5条,在拿5条数据,理解为5-10条数据(点击分页条
            应该拿到哪些数据)
		db.表名.find().count() - 获取到此表有多少条数据(做出分页条)

3、安装mongDBCompass软件:图形化界面,直观、好看、方便 - 仅仅用于我们方便查看

4、Node.js操作mongoDB - Node.js官方并没有提供过操作数据库的API

1、安装第三方模块:mongoose

2、使用步骤:
	1、引入:var mongoose=require("mongoose");
	2、连接数据库:mongoose.connect("mongodb://127.0.0.1/h52302");
	3、创建出一个新的数据表的同时,设置数据类型的控制,防止用户乱输
		var UserSchema=mongoose.Schema({
			name:String,
			pwd:String,
			age:Number,
			email:String,
			vip:String
		})
		//		模型名随意的   数据的控制   表名,没有则为创建,有了则为选中!
		var User=mongoose.model("User",UserSchema,"user")

	4、增:21、创建要插入的对象
		var x=new User({
			name:"袍哥1",
			pwd:"123456",
			age:"123",
			email:"pg@qq.com",
			vip:"1"
		})
		2、创建好的对象插入到数据表中
		x.save().then(()=>{
			console.log("插入完毕了,你要干什么,必须放在这个里面,因为他也是异步")
		})

	5、删:
		User.deleteOne/deleteMany({条件}).then(()=>{
			console.log("删除完毕了,你要干什么,必须放在这个里面,因为他也是异步")
		})

	6、改:
		User.updateOne/updateMany({条件}).then(()=>{
			console.log("修改完毕了,你要干什么,必须放在这个里面,因为他也是异步")
		})

	7、查:
		User.find({条件}).then((rs)=>{
			rs->查询到的数据
		})
	
	条件的写法和上午的写法是一模一样的!

	目前:前端能传到后端的技术,只有一个:form表单,action属性可以随便自定义一个路由名称,后端解析
        此路由就可以通过Object.query.键名得到前端传来的东西