JavaScript第五周知识点总结

172 阅读19分钟

一.对象,函数补充

(一)保护对象

保护对象的属性和方法

1.四大特性

(1)四大特性定义及功能

value: 1001, //值
writable: true, //开关:控制是否可以被修改 - 默认值:true
enumerable: true, //开关:控制是否可以被for in循环遍历到 - 默认值:true		  
configurable: true //开关:控制是否可以被删除 - 默认值:true,
configurable是总开关:一旦设置为false,其他特性不可以再修改,
而且它本身也是一旦设置为false,就不可更改

(2)四大特性设置

	Object.defineProperty(对象名,"属性名",{
	 			修改四大特性
			})
                     调用一次方法只能保护一个属性的四大特性

	Object.defineProperties(对象名,{
				"属性名":{修改四大特性},
				...
			})
		至少方法只调用了一次

		四大特性甚至不能防止添加

2.三个级别

  1、防扩展:防止添加
		Object.preventExtensions(obj);

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

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

3.,为什么说保护对象不重要?

1、如果不用面向对象开发,那也没有对象可保护
2、很少使用
3、别人一般来说不可能知道你取的对象名字叫什么

四大特性,其实应该叫六大特性 - 可以帮助我们做出动态数据

  Object.defineProperty(obj,"name",{
			get:()=>{
				console.log("获取数据会进行拦截");	
			},
			set:v=>{
				console.log("设置数据会进行拦截");
				v;//拦截到的新数据
				d1.innerHTML=v;
			}
		})

三阶段有一个框架叫做vue,vue中的所有数据都是动态数据,意味着他的底层就是做了拦截操作

(二)对象的深浅拷贝

1、浅拷贝:
        var obj1={"name":"obj1"};
        var obj2=obj1;

2、深拷贝:
        var obj1={"name":"obj1"};
        var obj2={...obj1}

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

(三)Error对象

1、以后工作/学习的目的

  	1、快速找到错误
	2、记得要放用户

2、***浏览器自带4种错误类型:可以快速找到自己的错误

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

3、只要发生错误,就会报错,会导致后续代码终止(闪退)

    错误处理:就算发生错误,也不希望报错,而是给出一个错误提示,让后续代码可以继续执行
    语法:
	try{
		只放入你可能出错的代码
	}catch(err){
		发生错误后才会执行的代码
		alert(err);//err就是我们的错误提示:只不过是英文的
		alert("中文的错误提示,来提示用户");
	}

	try...catch...的性能非常差,几乎是所有代码里最差的,放在try中的代码效率
            会被降到最低
            
	*可以用一个技术代替他:分支结构
            
	*开发经验:记住一切的客户端输入/用户输入都可能乱输
            但只要你做好该做的防护就不会出错(!isNaN、正则)

4、抛出自定义错误,只要是错误,后续代码都不会执行

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

5、ES5:严格模式

开启:"use strict"; - 写在任何一个作用域的顶部都可以        
作用:
	1、禁止了全局污染,使用变量之前必须先创建变量
	2、将静默失败升级为了错误

(四)柯里化函数

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

(五)百度地图

1、定位技术有哪些?

1、GPS - 美国(卫星定位):1、缴纳版权费用   2、安全性低

2、北斗 - 中国自主:最初并不是民用,而是军用,使用的是惯性定位(定位并不精准)
		   后期发展为了民用,添加了卫星定位(更精确)
                       
3、基站定位 - 信号的范围发射,可以检测到你现在的信号属于哪个范围。
    
4、IP定位 - 在网不要乱说话,乱造谣,要坐牢。
    

2、网站的定位技术都是使用的GPS,并不需要学习如何使用GPS

3、开发者如何使用:

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

(六)匿名函数: 没有名字的函数,有两种用法

1、自调:只能执行一次,好处:函数中的没用的变量是会自动释放的,可以用于代替全局代码写法,两者很相似:都只会执行一次,但是自调会释放

    (function(){
		console.log(1);
	})();

2、回调:匿名函数不是自调,就是回调

    elem.on事件名=function(){}
    arr.sort(function(){})
    var obj={
	"方法名":function(){}
	}
            
一切的回调函数,都可以简化为箭头函数

(七)设计模式: 不仅仅局限于前端,是一种编程思想,越来越复杂,对前端人员要求也越来越高

1、单例模式:也称之为单体模式,保证一个类仅有一个实例对象,并且提供一个访问它的全局访问点,为三阶段的vue,new Vue();

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

		推荐写法:
		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.sayHello=function(){
			console.log(this.name);
		}
		
		var llc=new h52301("兰林传",18);
		var yxw=new h52301("因性温",19);
		
		console.log(llc);
		console.log(yxw);
		console.log(yxw==llc);

		llc.sayHello();
		yxw.sayHello();

		何时使用:我们的页面只有一个弹出框

2、发布订阅模式 :为三阶段vue的bus总线用到的底层原理就是我们的发布订阅模式

    let obj={};
		//创建订阅者
		function on(id,fn){
			if(!obj[id]){//判断有没有此id,
                                         //没有就创建了一个空数组
				obj[id]=[];
			}
			obj[id].push(fn);
		}
		on("老袍",(msg)=>{console.log("小兰来了",msg)});
		on("老袍",(msg)=>{console.log("小尹来了",msg)});
		on("老袍",(msg)=>{console.log("小张来了",msg)});
		on("老袍",(msg)=>{console.log("小李来了",msg)});
		on("老袍",(msg)=>{console.log("小赵来了",msg)});
		console.log(obj);//{"老袍":[fn,fn,fn,fn,fn]}
		
		//发布者的操作
		function emit(id,msg){
			obj[id].forEach(fn=>fn(msg));//obj["老袍"].forEach
		}
		btn.onclick=()=>{
			emit("老袍","一支穿云箭");
		}

(八)事件轮询

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

1、宏任务: 不会再卡住单线程应用,可以让后续代码先执行,但是多个宏任务同时存在时,执行顺序就是新问题

    1、定时器:setIntervalsetTimeout
    2Ajax

2、微任务: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);//promise的回调函数提供了
                                                          //一个形参函数,可以用于放行
		console.log("后续代码");

二.Node.js

1、基本内容:

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

拥有服务器的方式:
	1、买 - 对中小型公司不友好
	2、买一台配置好一点的微机 - 对于别的行业的公司也不太划算
	3、租云服务器 - 腾讯云、阿里云、新浪云、百度云... 配置自选
		
对于我们开发人员来说
	硬件服务器 - 人人都有一台电脑
	软件服务器 - 中间件(软件可以将你的电脑变成一台服务器,
                               人人都可以访问你,就是我们要学习的Node.js

2.软件架构:服务器很重要的原因?

    C/S - Client客户端/Server服务器端
		举例:
			QQ、微信、大型网络游戏
		优点:
			1、用户体验感较好
			2、运行稳定
			3、对带宽的要求低

		缺点:
			1、占硬盘空间
			2、更新过于麻烦 - 服务器端和客户端都要更新

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

		优点:
			1、几乎不占硬盘
			2、更新简单 - 只需要更新服务器端
			3、无需考虑电脑配置

		缺点:
			1、用户体验感较差,但逐渐提高(越来越好,尤其是现在出了个云平台,
                            根本不用考虑电脑配置)
                            
			2、对带宽的要求高(其实还好,网速越来越快)

(一)概述

1.概念

    不是JS,但是语法和JavaScript非常相似,竞争对手:Java、C++、C#、Python...
    做的事和服务器端其他语言是一致: 和数据库进行交互,成为了一个前端到数据库的中间桥梁   

2.目的

1、使用代码搭建一个服务器&文件系统, 可以让其他
2、Node.js如何沟通前端和数据库
3、全栈:图书管理系统(HTML+CSS+JS+Node+Mongo)

(二)安装步骤

  1.node-v18.15.0-x64.msi - 一路往下点,哪里点不动了,就把哪里勾上,千万不要取消任何东西
  
  版本:16年初(0.12)	16年中(4.xx)	16年末(6.xx) 
      
  更新速度快,意味着:发展迅速,有前景,其实也没有多大的变化,更新的最多的是提升了性能
  
  2.检查是否安装成功:打开cmd输入:node -v - 查看版本号,如果有版本号代表已经安装成功
      
  3.其实安装的这个node.js就是一个运行环境

(三)如何运行

1、交互模式 - 临时测试

    打开cmd输入:node回车,就可以开始敲代码

2、脚本/文件模式 - 正式开发中

    1、先创建xx.js,里面书写代码
    2、打开cmd输入:node 文件的绝对路径

3、安装插件,前提:至少两个方式能够成功,才可以安装插件

       vscode - code runner:对着文件出右键,第一个选项就是code runner,
       右上角有一个开始按钮
       
       code runner使用时要设置default language为JavaScript

(四)Node.js和JS的区别

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

(五)模块(module): 每一个xx.js文件,都可以称之为是一个模块

1、模块化开发:

    如果以一个网站来说,我们可以按功能分为很多模块:商家模块、商品模块、
    促销模块、用户模块、产品模块....
    
    分工合作:将每个模块交给对应的人,完成,最后再由【主模块】进行引入
    

1、每一个模块都有一个操作,可以用于公开/暴露自己的成员

	exports:Node.js自带的一个预定义变量,可以直接使用,是一个对象,放在此对象
                里面的东西,就是允许公开的东西
	语法:
		1exports.属性名=属性值;
		2module.exports={
			属性名:属性值,
			...
                            }
                                  
	错误导出法:
		exports={
			name:"袍哥",
			age:18,
                        hobby:"学习"
                               }

2、每一个模块(主模块)都有一个操作,可以用于导入/引入其他模块

       requireNode.js自带的一个预定义变量,可以直接使用,是一个函数,
                     函数中需要书写出引入模块的路径
                     
        语法:var x=require("./文件名")

笔试题:exports和module.exports有什么区别?

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

2、模块的分类:

   1、官方模块 - 今日目标,大概有二十几个,但是重要的其实只有几个
   2、第三方模块 - 提供了不清楚方模块没有的东西,有一个网址npm可以去下载 再
   3、自定义模块

***Node.js最大的特点:快

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

3、官方模块:不需要下载,在你安装node.js环境的时候就已经带上了,有的需要引入可能

1、Global模块:不需要引入的,可以直接使用

    提供了:
		1、五个预定义变量,可以直接使用
                    1、__filename - 获取当前文件完整的绝对路径
                    
                    2、*__dirname - 获取当前文件绝对路径,不包含文件的名字
                    何时:vscode可能不支持node.js上书写相对路径,只能写绝对路径 
                    
                    、*exports - 空对象,可以用于公开暴露自己的成员
                    
                    4、*require - 函数,可以用于导入其他模块
                    
                    5、***module - 指代当前模块本身,甚至包含着以上4个操作
                    
		2、定时器(周期性、一次性、瞬间定时器):只不过用法和当初一模一样
                    
                3console也不是当初的console,只不过用法和当初一模一样

2、querystring模块:解析查询字符串,使其变成一个对象,可以获取到前端传到后端的消息

3、***url模块

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

4、Buffer模块:

    缓冲区,可以将数据变成一个16进制的数字,可以理解为是Node.js中的一种新的数据类型,
    但是绝对不会手动使用,因为看不懂
    
    但是后面的一些API可能会被动都到Buffer,因为Node.js中大部分的API,支持Buffer

5、*****fs模块

    需要引入:var fs = require('fs');

	*异步读取文件:fs.readFile("文件路径",(err,buf)=>{
			buf->读取到的内容
                            })

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

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

6、http模块 - 超级重点:搭建服务器

    //引入了http(搭建服务器)、url(区分开路由和请求消息)、fs(读取文件响应给用户看)
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"){//判断路由的不同,读取不同的页面给用户看
//res:response(响应)对象,有一个方法:res.end(响应的内容) - 可以响应给前端想要的东西
fs.readFile("./public/html/index.html",(err,buf)=>{
		res.end(buf);//res.end只能用一次
	})
}
})

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

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

8.模块(每个.js文件)的分类

       1、官方模块:不需要下载,再安装Node.js环境的时候就已经自带了,
       但是有的模块需要引入:require("模块名");
       2、第三方模块
       3、自定义模块:自己书写的xx.jsrequire("./模块名");

9.为什么有的模块引入要./有的又不用加./

自定义模块:分为2大类
	1、文件模块:创建xx.js去公开需要公开的内容,主模块要引入,
                   必须写为require("./模块名");
                   
        2、目录模块: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");

其实真实开发中,我们程序员用的最多的是文件模块,目录模块的第三种方式其实根本不是给人用的
    (第三方模块下载后会自动创建此文件夹)

10.如何下载第三方模块

npm工具:Node Package ManagerNode.js的模块/包管理器,专门用于管理第三方模块的,

作用:下载、更新、删除、维护包之间的依赖关系

打开网址:npm官网https://www.npmjs.com/
    
搜索你需要用到的模块:尽量用带有完全符合标签的那个包,或者是 第一个包:
	1、打开cmd:检查npm是否安装成功:npm -v
	2、在你的项目之中,再打开cmd
	3、下载:npm i 包名
	4、更新:npm up 包名
	5、删除:npm un 包名

(六) mongoDB

mongo就是基于json的数据库,json就是JavaScript Object Notation(对象表示法)

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 - 在上一个命令行可以查看我们是否链接成功 
            客户端开启成功

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,最多存储500个,意味着这个数据表做了限制,不推荐
    
	2、查看目前所有的数据表:db.getCollectionNames();
            
	3、删除数据表:db.表名.drop();

3、*****数据的操作

1、增:
      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"}])

2、删:
      db.表名.remove({}) - 不推荐,删除数据库中所有的数据
      db.表名.remove({name:"任小波"}) - 会删除数据库中name:"任小波"的所有数据

3、改:
      db.表名.update({条件},{$set:{新内容}});
      举例:db.表名.update({name:"任小波"},{$set:{pwd:"123123"}});

4、*查:
      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() - 获取到此表有多少条数据(做出分页条)

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

4、Node.js操作mongoDB:

1、安装第三方模块:mongoose

2、使用步骤:

        1、引入:const mongoose = require('mongoose');
        
	2、连接数据库:mongoose.connect("mongodb://127.0.0.1/数据库名称");
            
	3、创建出一个新的数据表的同时,设置数据类型的控制,防止用户乱输
		const UserSchema=mongoose.Schema({
			age: Number,
			pwd: String,
			email: String,
			vip: String,
			name: String,
		})
		//		模型名    类型限制     
		var User=mongoose.model("User",UserSchema,"数据表名");
                    
	4、增:
		var x=new User({//仅仅只是创建出了一个x对象,并没有放入到数据库之中
			age: "20",
			pwd: "123123",
			email: "dy@qq.com",
			vip: "0",
			name: "dy",
		})

		x.save((err)=>{
			console.log("新增成功后要干什么");
		})

	5、删:
		User.remove/deleteOne/deleteMany({条件},(err)=>{
                    // - 作者不推荐remove在mongoose之中使用
			console.log("删除成功后要干什么");
		})

	6、改:
		User.update/updateOne/updateMany({条件},{新内容},(err)=>{
                    // - 作者不推荐update在mongoose之中使用
			console.log("修改成功后要干什么");
		})

	7、查:
		User.find({条件},(err,result)=>{
			result就是你的查找到的结果
		})

强调:mongoose不要下载

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