JavaScript、Node.js - 第五周

95 阅读13分钟

day21(js)

一、保护对象

保护对象的属性和方法

1.1 四大特性(不能防止添加)

var zs = {
            "id" : 1001,
            "name" : '张三',
            "salary" : 5000
        }
        console.log(Object.getOwnPropertyDescriptor(zs,"id"));
        //{value: 1001, writable: true, enumerable: true, configurable: true}
  • value: 1001 实际保存值的地方
  • writable: true 控制着是否可以被修改 - 默认值:都为true
  • enumerable: true 控制着是否可以被for in循环遍历到 - 默认值:都为true
  • configurable: true 控制着是否可以被删除 - 默认值:都为true,总开关:一旦设置为false,其他特性不可以在修改,而且它本身也是一旦设置为false,不可逆

1.2 修改四大特性

Object.defineProperty(对象名,"属性名",{
        修改四大特性//调用一次方法只能保护一个属性的四大特性
})
Object.defineProperties(对象名,{
        "属性名":{修改四大特性},
        ...
})
<script>
    // 保护对象的四大特性
    var zs = {
        "id" : 1001,
        "name" : '张三',
        "salary" : 5000
    }
    console.log(Object.getOwnPropertyDescriptor(zs,"id"));//{value: 1001, writable: true, enumerable: true, configurable: true}
    Object.defineProperty(zs,"id",{
        writable : false,//不能修改
        configurable : false//不能删除
    })
    Object.defineProperty(zs,"name",{
        configurable : false//不能删除
    })
    Object.defineProperty(zs,"salary",{
        enumerable : false,//不能被for in遍历
        configurable : false//不能删除
    })

    zs.id = 1002
    console.log(zs);//id : 1001
    delete zs.id
    console.log(zs);//删除不了了
    for (var i in zs) {
        console.log(zs[i]);//遍历不到salary
    }

    Object.defineProperties(zs,{
        "id" : {
            writable : false,//不能修改
            configurable : false//不能删除
        },
        "name" : {
            configurable : false
        }
    })
</script>

1.3 三个级别

  • 防扩展:防止添加 Object.preventExtensions(obj);
  • 密封:防止添加和删除 Object.seal(obj);
  • 冻结:防止添加和删除和修改 Object.freeze(obj);
<script>
    // 保护对象的三个级别
    var zs = {
        "id" : 1001,
        "name" : '张三',
        "salary" : 5000
    }
    // 防扩展:防止添加
    /* Object.preventExtensions(zs)
    zs.age = 18
    console.log(zs);//{id: 1001, name: '张三', salary: 5000} */

    // 密封:防止添加和删除
    /* Object.seal(zs)
    zs.age = 18
    delete zs.id
    console.log(zs);//{id: 1001, name: '张三', salary: 5000} */

    // 冻结:防止添加删除修改
    Object.freeze(zs)
    zs.age = 18
    delete zs.id
    zs.salary = 6000
    console.log(zs);//{id: 1001, name: '张三', salary: 5000}
</script>

1.4 动态数据

<div id="div"></div>
<script>
    // 做出动态数据
    var zs = {
        "name" : "张三"
    }
    div.innerHTML = zs.name
    Object.defineProperty(zs,"name",{
        get : () => {
            console.log('获取数据会进行拦截');
        },
        set : v => {
            console.log('设置数据会进行拦截');
            div.innerHTML = v//v是拦截到的新数据
        }
    })
    zs.name = 'lily'//页面也会变成lily
</script>

二、深浅拷贝

2.1 数组的深浅拷贝

<script>
    // 数组的深浅拷贝
    var arr = [1,2,3,4,5]
    // 浅拷贝
    var arr1 = arr;
    console.log(arr);//[1, 2, 3, 4, 5]
    console.log(arr1);//[1, 2, 3, 4, 5]
    arr1.length--
    console.log(arr);//[1, 2, 3, 4]
    console.log(arr1);//[1, 2, 3, 4]
    // 深拷贝
    var arr2 = arr.slice()
    // var arr2 = [...arr]//...是去掉数组的[]
    console.log(arr);//[1, 2, 3, 4]
    console.log(arr2);//[1, 2, 3, 4]
    arr2.length--
    console.log(arr);//[1, 2, 3, 4]
    console.log(arr2);//[1, 2, 3]
</script>

2.2 对象的深浅拷贝

<script>
    // 对象的深浅拷贝
    var zs = {
        "name" : "张三"
    }
    // 浅拷贝
    var zs1 = zs
    console.log(zs);//{name: '张三'}
    console.log(zs1);//{name: '张三'}
    zs1.name = '张三1'
    console.log(zs);//{name: '张三1'}
    console.log(zs1);//{name: '张三1'}

    // 深拷贝
    // var zs2 = {...zs}//...是去掉对象的{}
    var zs2 = JSON.parse(JSON.stringify(zs))//JSON.stringify()是加上{},JSON.parse()是去掉()
    console.log(zs);//{name: '张三1'}
    console.log(zs2);//{name: '张三1'}
    zs2.name = '张三2'
    console.log(zs);//{name: '张三1'}
    console.log(zs2);//{name: '张三2'}
</script>

三、Error对象:错误

4.1 浏览器自带4种错误类型

  • 语法错误:SyntaxError - 一定是你的符号写错了
  • 引用错误:ReferenceError - 没有创建就去使用了
  • 类型错误:TypeError - 不是你的方法,你却去使用了
  • 范围错误:RangeError - 只有一个API会碰到:num.toFixed(d);//d取值范围:0~100之间

4.2 错误处理

语法:

try{
       只放入你可能出错的代码
}catch(err){
       发生错误后才会执行的代码
       alert(err);//err就是我们的错误提示:只不过是英文的
       alert("中文的错误提示,来提示用户");
}
  • try...catch...的性能非常差,几乎是所有代码里最差的,放在try中的代码效率会被降到最低
  • 可以用一个技术代替他:分支结构
<script>
   // 错误处理
   var num = parseFloat(prompt('请输入一个数字:'));
   var d = parseInt(prompt('请输入要保留的小数位数'));
   // 方法一 try...catch...
   /* try {
       console.log(num.toFixed(d));
   } catch (err) {
       console.log(err);
       console.log('小数位数必须为0-100');
   } */
   // 方法二  分支语句
   if (d >= 0 && d <= 100) {
       console.log(num.toFixed(d));
   } else {
       console.log('小数位数必须为0-100');
   }
   console.log('后续代码');
</script>

4.3 抛出自定义错误

throw new Error("自定义错误消息");

4.4 ES5:严格模式

  • 开启:"use strict"; - 写在任何一个作用域的顶部都可以
<script>
   /* a = 1;
   console.log(a);//a */
   "use strict"
   a = 1;
   console.log(a);//Uncaught ReferenceError: a is not defined
</script>
  • 作用:
    1. 禁止了全局污染,使用变量之前必须先创建变量
    2. 将静默失败升级为了错误

四、柯里化函数

function add(a){
       return function(b){
               return function(c){
                       console.log(a+b+c);
               }
       }
}
add(3)(5)(7);//15

day22(js)

一、定位技术

1.1 定位技术有哪些

  • GPS - 美国(卫星定位):1、缴纳版权费用 2、安全性低
  • 北斗 - 中国自主:最初并不是民用,而是军用,使用的是惯性定位(定位并不精准),后期发展为了民用,添加了卫星定位了(更精确了)
  • 基站定位 - 信号的范围发射,可以检测到你现在的信号属于哪个范围。
  • IP定位

1.2 网站的定位技术都是使用的GPS

1.3 开发者如何使用百度/高德地图

  • 打开百度:搜索百度地图开放平台
  • 注册、登录百度账号
  • 拉到最下面、点击立即注册成为开发者
  • 进入控制台
  • 应用管理->我的应用->创建应用->实名认证->获得密钥(AK)
  • 鼠标移动到导航条->放到开发文档上->web开发->JavaScript API->示例DEMO
  • 挑选出你喜欢的地图,然后复制全部代码(HTML/CSS/JS),到你需要的位置
  • 查询经纬度:api.map.baidu.com/lbsapi/getp…
  • 百度地图你看上的每一个都可以混搭在一起,但是一定要注意版本:普通版(老) 和 webGL(新),是不可以混搭的

二、匿名函数

没有名字的函数

2.1 匿名函数的两种用法

  • 自调:只能执行一次,函数中的没用的变量是会自动释放的
<script>
    (function(){
        console.log(1);
    })()
</script>
  • 回调:匿名函数不是自调,就是回调,切的回调函数,都可以简化为箭头函数
elem.on事件名=function(){}
    arr.sort(function(){})
    var obj={
            "方法名":function(){}
    }

三、设计模式

不仅仅局限于前端,它是一种编程思想

3.1 单例模式

也称之为单体模式,保证一个类仅有一个实例对象,并且提供一个访问它的全局访问点

<script>
    // 最简单的单例模式 利用let不允许重复声明的特性 不推荐
    /* let obj = {
        "name" : "张三",
        "getName" : function () {
            return this.name
        }
    }
    console.log(obj);
    console.log(obj.name);
    console.log(obj.getName()); */
    // 推荐写法
    var h52301 = (function () {
        let state = null
        return function(name,age) {
            this.name = name;
            this.age = age;
            if (state) {
                return state
            }
            return state = this
        }
    })()
    h52301.prototype.say = function () {
        console.log(this.name);
    }

    var zs = new h52301('张三',18)
    console.log(zs);//{name: '张三', age: 18}
    var ls = new h52301('李四',20)
    console.log(ls);//{name: '张三', age: 18}
    zs.say()//张三
    ls.say()//张三
    console.log(zs==ls);//true
</script>

3.2 发布订阅模式

<button id="btn">发布</button>
<script>
    let obj = {};
    // 创建订阅者
    function on(id,fn) {
        if (!obj[id]) {
            obj[id] = []
        }
        obj[id].push(fn)
    }
    on("张三",(msg)=>{console.log('1111',msg);})
    on("张三",(msg)=>{console.log('2222',msg);})
    console.log(obj);//{"张三":[fn,fn]}
    // 发布者的操作
    function emit(id,msg) {
        obj[id].forEach(fn=>fn(msg))
    }
    btn.onclick = () => {
        emit('张三','5555')
    }
</script>

四、事件轮询

js其实是单线程引用,代码必然是从上向下,一步一步的执行,如果某一块代码非常耗时,可能会导致整个页面卡住,尤其如果你把js放在head之中,会看到页面是一个白板

4.1 宏任务:

不会再卡住我们的单线程应用,可以让后续代码先走,但是多个宏任务同时存在,到底谁先执行谁后执行,分不清

  • 定时器:setInterval和setTimeout
  • Ajax
<script>
    setTimeout(function(){
        console.log(1);
    },Math.random()*3000)

    setTimeout(function(){
        console.log(2);
    },Math.random()*3000)

    setTimeout(function(){
        console.log(3);
    },Math.random()*3000)
    console.log('后续代码');
</script>

4.2 微任务:

ES6提供的Promise对象,可以控制异步代码执行的顺序

<script>
    function ajax1(resolve) {
        setTimeout(()=>{
            console.log(1);
            resolve()
        },Math.random()*3000)
    }
    function ajax2() {
        return new Promise
        (resolve=>{
            setTimeout(()=>{
                console.log(2);
                resolve()
            },Math.random()*3000)
        })
    }
    function ajax3() {
        setTimeout(()=>{
            console.log(3);
        },Math.random()*3000)
    }
    new Promise(ajax1).then(ajax2).then(ajax3)
    console.log('后续代码');
</script>

day01(Node)、day02(Node)

一、软件架构

1.1 C/S(Client客户端/Server服务器端)

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

1.2 B/S(Browser浏览器端/Server服务器端)

  • 优点
    1. 几乎不占硬盘
    2. 更新简单 - 只需要更新服务器端
    3. 对电脑配置要求不高
  • 缺点
    1. 用户体验感较差
    2. 对带宽的要求高

二、Node.js

不是JS,但是语法和JavaScript非常相似,做的功能绝对不是特效!做的事和服务器端其他语言是一致(和数据库进行交互,成为了一个前端到数据库的中间桥梁)

2.1 目的:

  1. 使用代码搭建一个服务器&文件系统(服务器文件可以放在任何位置,但是不在你的电脑里,你可以根据网址来访问到我的东西)
  2. Node.js如何沟通前端和数据库

2.2 Node.js安装

  1. node.js官网下载-安装
  2. 检查你安装成功没:打开cmd输入:node -v - 查看版本号,如果有版本号代表你已经安装成功!

2.3 Node.js如何运行:3种

  • 交互模式 - 临时测试:打开cmd输入:node回车,就可以开始敲你的"js"代码
  • 脚本/文件模式 - 正式开发中:先创建xx.js,里面书写自己的代码 -> 打开cmd输入:node 文件的绝对路径
  • 安装插件:前提是至少前面两个方式能够成功,才可以安装插件。vscode的插件是code runner:对着文件出右键,第一个选项就是code runner,或者 右上角有一个开始按钮

2.4 js和node的区别

  • 相同点:都可以使用一切的ECMAScript的东西包括一切的API都可以使用,在服务器端不存在任何浏览器,所以不必担心兼容问题
  • 不同点
    1. JavaScript:DOM+BOM - 做特效
    2. Node.js:有很多的模块

2.5 Node.js最大的特点

  • 快、非常快
  • 因为官方提供的东西少,甚至连数据库的操作API都没有提供的
  • 使用了chrome浏览器的v8引擎

三、模块(module)

每一个xx.js文件,都可以称之为是一个模块

3.1 模块化开发

如果以一个网站来说,我们可以按功能分为很多模块:商家模块、商品模块、促销模块、用户模块、产品模块....

3.2 分工合作

将每个模块交给对应的人,完成,最后再由【主模块】进行引入
  • 每一个模块都有一个操作,可以用于公开/暴露自己的成员:exports。Node.js自带的一个预定义变量,可以直接使用,是一个对象,放在此对象里面的东西,就是允许公开的东西

语法

exports.属性名=属性值;
module.exports={
    属性名:属性值,
    ...
}
console.log(exports);//{}
// 方法一
/* exports.size = function (r) {return Math.PI*r*r}//圆的面积
exports.per = function (r) {return Math.PI*r*2}//圆的周长 */
// 方法二
module.exports = {
    size : function(r){return Math.PI*r*r},
    per : function(r){return Math.PI*r*2}
}
  • 每一个模块(主模块)都有一个操作,可以用于导入/引入其他模块require。Node.js自带的一个预定义变量,可以直接使用,是一个函数,函数中需要书写出引入模块的路径 语法:var x=require("./文件名")
  • 语法
var fz1 = require('./06-分支模块1')
console.log(fz1);//{ size: [Function (anonymous)], per: [Function (anonymous)] }
console.log(fz1.size(2));//12.566370614359172
console.log(fz1.per(3));//18.84955592153876

3.3 exports和module.exports有什么区别

  • 语法,写法,用法不同
  • 都是用于公开暴露自己的成员的
  • 但是exports={},写法是错误的
  • 其实Node.js底层有一句话:exports=module.exports
  • 其实真正做公开功能的是module.exports
  • 如果你使用了exports={};其实是你创建了一个新的空对象,把module.exports覆盖了,所以不在具有公开的功能

四、模块的分类:

4.1 官方模块

不需要下载,在你安装node.js环境的时候就已经带上了,但是某的模块可以需要引入,某的模块可能不需要引入:
  • Global模块:不需要引入的,可以直接使用
    1. __filename - 获取当前文件完整的绝对路径
    2. __dirname - 获取当前文件的文件夹的绝对路径
    3. exports - 空对象,可以用于公开暴露自己的成员
    4. require - 函数,可以用于导入其他模块
    5. module - 指代当前模块本身,甚至包含着以上4个操作
    6. 定时器(周期性、一次性、瞬间定时器)
      // 周期性定时器
      setInterval(function(){
          console.log(1);
      },500)
      // 一次性定时器
      setTimeout(function(){
          console.log(2);
      },1200)
      // 瞬间定时器
      setImmediate(function(){
          console.log(3);
      })
      
    7. console
  • querystring模块:解析查询字符串,使其变成一个对象,可以获取到前端传到后端的消息
    1. 需要引入:var qs = require('querystring');
    2. 作用:解析url查询字符串部分的功能
    3. var obj=qs.parse("查询字符串");
    4. 想要获得前端传来的每一个部分:obj.键名;
    5. 如果前端传来的是一个完整的url网址,他就解析不了了!
    const qs = require('querystring')
    console.log(qs);
    // 解析字符串
    var str = 'name=dy&pwd=123123&vip=1&email=610147162@qq.com';
    var obj = qs.parse(str);
    console.log(obj);
    console.log(obj.name);//dy
    
  • url模块
    1. 需要引入:var url = require('url');
    2. 作用:提供了解析url各个部分的功能
    3. var objUrl=url.parse("网址",true);//支持第二参数,是一个布尔值,默认为false,一旦设置为true,自动使用querystring模块的parse方法去解析查询字符串部分
    4. 查询字符串:objUrl.query.键名; - 前端form表单提交传到后端的东西
    5. 路由/文件相对路径/请求地址:objUrl.pathname - 判断路由的不同,去读取不同的HTML发送给我们的用户看
    var url = require('url')
    // console.log(url);
    //假设,前端向后端传来的完整网址:
    var str="https://www.paoge.com:443/new/index.html?name=dy&pwd=123123&vip=1&email=610147162@qq.com";
    var obj = url.parse(str,true)//trun代表自动解析查询字符串,可传也可以不传,默认值为false
    console.log(obj.query.name);//name
    
  • Buffer模块:缓冲区,可以将数据变成一个16进制的数字
    var buf = Buffer.from([1,2,3,4,5])
    var buf1 = Buffer.from('hello你好')
    console.log(buf);//<Buffer 01 02 03 04 05>
    console.log(buf1);//<Buffer 68 65 6c 6c 6f e4 bd a0 e5 a5 bd>
    console.log(buf1.toString());//hello你好
    
  • fs模块
    1. 需要引入:var fs = require('fs');
    2. 读取文档:
    var fs = require('fs')
    // console.log(fs);
    // 读取文档 异步
    fs.readFile(__dirname+'/public/01.txt',function(err,buf){
        console.log(err);//null
        console.log(buf);//<Buffer e4 bb 8a e5 a4 a9 e6 98 9f e6 9c 9f e4 b8 89>
    })
    // 读取文档 同步
    /* var buf = fs.readFileSync(__dirname+'/public/01.txt')
    console.log(buf);////<Buffer e4 bb 8a e5 a4 a9 e6 98 9f e6 9c 9f e4 b8 89> */
    console.log('后续代码');
    
    1. 写入文档:
    var fs = require('fs')
    // console.log(fs);
    // 写入文档 异步
    fs.writeFile(__dirname+'/public/01.txt','写入的内容',function(){
        console.log('写入完毕后要做什么必须放在这里');
    })
    // 写入文档 同步
    /* fs.writeFileSync(__dirname+'/public/01.txt','写入的内容-同步')
    console.log('写入完毕'); */
    console.log('后续代码');
    
    1. 追加文档:
    var fs = require('fs')
    // console.log(fs);
    // 追加文档 异步
    fs.appendFile(__dirname+'/public/01.txt','追加的内容',function(){
        console.log('追加完毕后要做什么必须放在这里');
    })
    // 写入文档 同步
    /* fs.writeFileSync(__dirname+'/public/01.txt','写入的内容-同步')
    console.log('写入完毕'); */
    console.log('后续代码');
    
  • http模块:搭建服务器
    var http = require('http');
    var url = require('url');
    var fs = require('fs');
    // 创建服务器应用
    var app = http.createServer();
    // 为其绑定监听端口 http端口默认80
    app.listen(8008);
    // 为其绑定请求事件:http:请求-响应模式,必须要有一个请求,才有一个响应
    app.on('request',(req,res)=>{
        // req:request(请求)对象,它有一个属性叫做req.url,可以获取到前端传到后端的路由和请求消息,但是路由和请求消息是融为一体的,不方便我们获取某个部分,所有我们引入了url,进行进行解析,分开两个部分
        // console.log(req.url);//得到的是路由和请求消息/index.html?name=zs
        var obj = url.parse(req.url,true)
        // console.log(obj);
        // 保存路由
        var router = obj.pathname
        console.log(router);
        // 判断路由的不同读取不同的页面给用户看
        if (router == '/' || router == '/index.html') {
            fs.readFile('./public/index.html',(err,buf)=>{
                //res:response(响应)对象,他有一个方法:res.end(响应的内容) - 可以响应给前端想要的东西
                res.end(buf)
                console.log(1);
                console.log(err);
            })
        // match方法类似indexOf 但是支持正则 找不到返回null
        } else if (router.match(/html|css|js|json|ttf|woff|woff2|png|jpg/) !== null) {
            fs.readFile(`./public${router}`,(err,buf)=>{
                res.end(buf)
                console.log(2);
            })
        }
    })
    

4.2 第三方模块

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

4.3 自定义模块

自己书写的xx.js:require("./模块名");

  • 文件模块:创建xx.js去公开需要公开的内容,主模块要引入,必须写为require("./模块名");
  • 目录模块:3种用法
    1. 比如创建m1的文件夹,在其中创建index.js的文件,去公开需要公开的内容,主模块要引入,必须写为require("./m1");
    2. 比如创建m2的文件夹,在其中创建xx.js的文件,,去公开需要公开的内容,主模块要引入,必须写为require("./m2"),必须再创建一个package.json的配置文件,写入:{"main":"xx.js"};
    3. 创建一个文件夹必须名为:node_modules,再在其中创建出m3文件夹,在其中创建index.js的文件,去公开需要公开的内容,主模块要引入,必须写为require("m3");

day03(Node)

一、mongo

mongo就是基于json的数据库,json就是JavaScript Object Notation

1.1 安装&启动

  • 打开bin文件夹,里面有:mongo.exe(客户端) 和 mongod.exe(服务器端)
  • 在bin文件夹中打开cmd:输入:.\mongod.exe --dbpath=你想要保存的绝对文件夹路径; - 服务器开启成功,而且那个文件夹就保存着你以后要存储的所有的数据
  • 不要关闭mongo服务器的cmd
  • 再打开一个cmd:输入:.\mongo.exe - 在上一个命令行可以查看我们是否链接成功 - 客户端开启成功

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

  • 数据库的操作:
    1. 查询所有数据库:show dbs
    2. 创建/切换数据库:没有创建就是切换,use 数据库名称
    3. 查看当前选中的数据库:db
    4. 创建数据表:db.createCollection("表名")
    5. 删除数据表:db.dropDatabase()
  • 数据表的操作:
    1. 创建数据表:db.createCollection("表名",{size:5242880,capped:true,max:5000})最大存储空间为5mb,最多存储500个,意味着这个数据表做了限制,不推荐
    2. 查看目前所有的数据表:db.getCollectionNames();
    3. 删除数据表:db.表名.drop();
  • 数据的操作:
      • db.表名.save({键值对,...}) - 一次只能插入一条数据
      • db.表名.save([{},{},{},....]) - 一次插入多条数据
      • 举例:db.user.save([{name:"付楠",age:18,pwd:"666666",email:"fn@qq.com",vip:"0"},{name:"袍哥",age:19,pwd:"999999",email:"pg@qq.com",vip:"1"}])
    1. 删:
      • db.表名.remove({}) - 不推荐,删除数据库中所有的数据
      • db.表名.remove({name:"任小波"}) - 会删除数据库中name:"任小波"的所有数据
      • db.表名.update({条件},{$set:{新内容}});
      • 举例:db.表名.update({name:"任小波"},{$set:{pwd:"123123"}});
      • db.表名.find(); - 找所有
      • db.表名.find({pwd:"666666"}); - 找到所有的密码为666666的数据
      • db.表名.find({},{name:1,pwd:1}) - 找到所有的数据,但是只返回name和pwd
      • db.表名.find().sort({age:1}) - 按照age升序排列,-1为降序排列
      • db.表名.find({age:{$gte:18}}) - 拿到所有age大于等于18的数据
      • db.表名.find({name:/正则/}) - 甚至可以用正则(模糊查询)
      • db.表名.find().skip(5).limit(5) - 跳过前5条,再拿5条,理解为5-10条数据(第几个分页条显示第几条数据-第几条数据)
      • db.表名.find().count() - 获取到此表有多少条数据(做出分页条)

二、Node.js操作mongoDB

安装第三方模块:mongoose

2.1 使用步骤:

  • 引入
const mongoose = require('mongoose');
  • 连接数据库:mongoose.connect("mongodb://127.0.0.1/数据库名称");
  • 创建出一个新的数据表的同时,设置数据类型的控制,防止用户乱输
const UserSchema=mongoose.Schema({
        age: Number,
        pwd: String,
        email: String,
        vip: String,
        name: String,
})
//		模型名    类型限制     
var User=mongoose.model("User",UserSchema,"数据表名");
  • 增:
var x=new User({//仅仅只是创建出了一个x对象,并没有放入到数据库之中
        age: "20",
        pwd: "123123",
        email: "dy@qq.com",
        vip: "0",
        name: "dy",
})
x.save((err)=>{
        console.log("新增成功后要干什么");
})
  • 删:
User.remove/deleteOne/deleteMany({条件},(err)=>{// - 作者不推荐remove在mongoose之中使用
        console.log("删除成功后要干什么");
})
  • 改:
User.update/updateOne/updateMany({条件},{新内容},(err)=>{// - 作者不推荐update在mongoose之中使用
        console.log("修改成功后要干什么");
})
  • 查:
User.find({条件},(err,result)=>{
        result就是你的查找到的结果
})

三、练习

const mongoose = require('mongoose');//引入
// console.log(mongoose);
mongoose.connect('mongodb://127.0.0.1/h52301');//链接数据库
// 创建出新的数据表得到同时,设置数据类型的控制,防止用户乱输   不会限制用户的输入内容 但是传入数据库会自动变
const userSchema = mongoose.Schema({
    name:String,
    pwd:String,
    email:String ,
    vip:Number,
})
// User模型名  userSchema限制类型   user数据表名
var User = mongoose.model("User",userSchema,'user');
// 增
/* var x = new User({//仅仅只是创建了一个x对象,并没有放到数据库中
    name:'张三',
    pwd:'666',
    email:'zh@qq.com',
    vip:'2',
})
// console.log(x);
x.save((err)=>{//异步
    // console.log(err);
    console.log('新增成功!');
}) */
// 删
/* User.deleteOne({name:'张三'},(err)=>{
    console.log('删除成功');
}) */
/* User.deleteMany({vip:2},(err)=>{
    console.log('删除成功!');
}) */
// 改
/* User.updateOne({vip:2},{vip:1},(err)=>{
    console.log('修改成功!');
}) */
// 查
/* User.find({vip:1},{name:1,pwd:1,_id:0},(err,result)=>{
    console.log(result);//查询结果
}) */
// 跳过前两条 再拿3条
User.find({},(err,result)=>{
    console.log(result);
}).skip(2).limit(3)
var url = require("url");
var fs = require("fs");
// 创建服务器并且设置端口号为8008
var http = require("http");
var app = http.createServer();
app.listen(8008);
// 连接数据库
var mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1/h52301");
//创建数据表并且限制类型
const userSchema = mongoose.Schema({
    name:String,
    pwd:String,
    email:String,
    vip:Number,
});
// mongoose.model(参数1:模型名称(首字母大写), 参数2:Schema,参数3:数据库集合名称)
var User = mongoose.model("User",userSchema,"user");

// 绑定请求事件
app.on("request",(req,res) => {
    // console.log(req.url);//得到的是路由和请求消息
    var objUrl = url.parse(req.url,true);
    // console.log(objUrl);
    var router = objUrl.pathname;//路由
    console.log(router);
    if (router == '/' || router == "/index.html") {
        fs.readFile("./public/html/index.html",(err,buf) => {
            // console.log(err);
            res.end(buf);
        })
    } else if (router.match(/html/) !== null) {
        fs.readFile(`./public/html/${router}`,(err,buf) => {
            res.end(buf);
        })
    } else if (router == "/register") {
        // 增 注册
        User.find({},{name:1,_id:0},(err,result) => {
            /* console.log(result);//拿到数据库表的所有name
            [
                { name: '张黎' },
                { name: '刘洋' },
                { name: '杨念' },
                { name: '舒锦' },
                { name: '李莉' },
                { name: '张三' },
                { name: '李四' }
              ] */
            for (var i = 0; i < result.length; i++) {
                // 判断名字 result[i].name数据库表中的名字  objUrl.query.name前端传来的名字
                if (result[i].name == objUrl.query.name) {
                    res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='注册失败';location='status.html';</script></body></html>")
                    return false;
                }
            }
            // 注册
            /* var x = new User({//仅仅只是创建了一个x对象,并没有放到数据库中
                name:objUrl.query.name,
                pwd:objUrl.query.pwd,
                email:objUrl.query.email,
                vip:objUrl.query.vip,
            }) */
            var x = new User(objUrl.query);
            // console.log(x);
            x.save((err)=>{//异步
                res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='注册成功';location='status.html';</script></body></html>")
            }) 
        })
    } else if (router == "/login") {
        // 查 登录
        User.find({},{name:1,pwd:1,_id:0},(err,result) => {
            for (var i = 0; i < result.length; i++) {
                if (result[i].name == objUrl.query.name && result[i].pwd == objUrl.query.pwd) {
                    res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='登录成功';location='status.html';</script></body></html>")
                    return false;
                }
            }
            res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='登录失败';location='status.html';</script></body></html>")
        })
    } else if (router == "/updatePwd") {
        // 修改密码
        User.find({},{name:1,pwd:1,_id:0},(err,result) => {
            for (var i = 0; i < result.length; i++) {
                if (result[i].name == objUrl.query.name && result[i].pwd == objUrl.query.pwd) {
                    User.updateOne({name:objUrl.query.name},{pwd:objUrl.query.newpwd},(err) => {
                        res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='修改成功';location='status.html';</script></body></html>")
                    })
                    return false;
                }
            }
            res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='修改失败';location='status.html';</script></body></html>")
        })
    } else if (router == "/logout") {
        // 注销  删除
        User.find({},{name:1,pwd:1,_id:0},(err,result) => {
            for (var i = 0; i < result.length; i++) {
                if (result[i].name == objUrl.query.name && result[i].pwd == objUrl.query.pwd) {
                    User.deleteOne({name:objUrl.query.name},(err) => {
                        res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='注销成功';location='status.html';</script></body></html>")
                    })
                    return false
                }
            }
            res.end("<html><head><meta charset='utf-8'></head><body><script>sessionStorage.state='注销失败';location='status.html';</script></body></html>")
        })
    }
})