JavaScript学习 --- 第五周

117 阅读17分钟

DAY1

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

1、对象属性/方法的四大特性:
	{
        value: 1001, 
        //键值对中实际保存值的地方
	writable: true, 
        //开关:控制着是否可以被修改
        //默认值:都为true
	enumerable: true, 
        //开关:控制着是否可以被for in循环遍历到
        //默认值:都为true
	configurable: true 
        //总开关:控制着此属性或方法是否可以被删除
        //默认值:都为true,总开关-->值一旦设置为false,此属性的所有四个特性不可再修改,而且它本身也是一旦设置为false,不可逆
	}

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

    (2)、调用一次方法,只能保护多个属性的四大特性:
    
       Object.defineProperties(对象名,{
		"属性名1":{修改四大特性},
                    "属性名2":{修改四大特性},
			...
		})
		//至少方法只调用了一次
		//四大特性甚至不能防止添加
    //保护对象不重要:
//	1、前辈们都没保护
//	2、代码上线要加密,别人一般不可能知道你取的对象名字叫什么
		
3、属性的三个级别:
	1、防扩展:防止添加
		Object.preventExtensions(obj);

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

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



//四大特性,其实应该叫六大特性 - 可以帮助我们做出动态数据
Object.defineProperty(obj,"name",{
	get:()=>{
		console.log("获取数据会进行拦截");	
		},
	set:v=>{
		console.log("设置数据会进行拦截");
		v;//拦截到的新数据
		d1.innerHTML=v;
		}
	})
    //理解到这一块即可
    //vue框架中的所有数据都是动态数据,意味着他的底层就是做了拦截操作
    

2、*对象的深浅拷贝:

1、浅拷贝:

		var obj1={"name":"obj1"};
		var obj2=obj1;

2、深拷贝:

		var obj1={"name":"obj1"};
		var obj2={...obj1}

3、如何脱掉后端传来的数据的格式

//1.后端穿衣服:
    var jsonText=JSON.stringify(obj1);
    
//2.前端脱衣服:
    var jsonObj=JSON.parse(jsonText);
//此方法也能实现深拷贝

3、*Error对象:错误

1、作用:快速找到错误,用于放用户提示信息


2、***浏览器自带4种错误类型:可以快速找到自己的错误
        (1)语法错误:你的符号写错了
        SyntaxError 
        (2)引用错误:没有创建就去使用了
        ReferenceError
        (3)类型错误:不是你的方法,你却去使用了
        TypeError
        (4)范围错误:
        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:严格模式
    
(1)开启:"use strict"; - 写在任何一个作用域的顶部都可以
(2)作用:
        a、禁止了全局污染,使用变量之前必须先创建变量
        b、将静默失败升级为了错误

4、柯里化函数

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

DAY2

1、百度/高德地图:

 (1)网站的定位技术都是使用的GPS,而并不需要我们学习如何使用GPS,我们有现成:百度/高德地图

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

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

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

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

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

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

3、设计模式:

  不仅仅局限于前端,它是一种编程思想,越来越复杂,对于我们前端人员要求也越来越高了。如果你对设计模式有兴趣,可以了解一下21种设计模式

1、单例模式:

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

(1)举例:
一个班级只有一个班主任,只有一个太阳,一个国家只有一个主席,"唯一" "便于访问(全局访问的)",行为对象变成做单例

(2)如何实现:
a.最简单的单例模式:利用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("老袍","一支穿云箭");
		}

4、事件轮询:

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

1、宏任务:不会再卡住我们的单线程应用,可以让后续代码先走,我们慢慢跟着来,但是问题在于,多个宏任务同时存在,无法分清执行顺序

(1)、定时器:setInterval和setTimeout
(2)、Ajax

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)如何拥有服务器:

1、买 - 贵
2、买一台配置好一点的微机 - 对于其他行业的公司也不太划算
3、租云服务器 - 腾讯云、阿里云、新浪云、百度云... 配置自选:配置越好,价格越高,按年收费 4、对于我们开发人员来说
硬件服务器 - 人人都有一台电脑
软件服务器 - 中间件(软件可以将你的电脑配置成一台服务器,人人都可以来访问,就是我们要学习的Node.js)

2、软件架构:服务器很重要?

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

举例: QQ、微信、大型网络游戏

优点:
1、用户体验感较好
2、运行稳定
3、对带宽的要求低

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

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

举例:
网页版QQ、微信、游戏

优点:
 1、几乎不占硬盘
 2、更新简单 - 只需要更新服务器端
 3、电脑在垃圾都可以玩得起

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


3、Node.js:

(1)概述:

  不是JS,但是语法和JavaScript非常相似,他的竞争对手:Java、C++、C#、Python...

(2)学习目的:

1、使用代码搭建一个服务器&文件系统(服务器文件可以放在任何位置,但是不在你的电脑里,你可以根据网址来访问到我的东西)
2、Node.js如何沟通前端和数据库
3、全栈:图书管理系统(HTML+CSS+JS+Node+Mongo)
4、Node.js安装:node-v18.15.0-x64.msi
  • 检查是否安装成功:
  • 打开cmd输入:node -v 查看版本号,如果有版本号代表你已经安装成功!其实你安装的这个node.js就是一个运行环境而已!我们书写“js”不再需要浏览器了,因为根本写的就是不是js,而是node.js,只不过语法和js非常相似
5、Node.js如何运行:3种
(1)、交互模式 - 临时测试
  • 打开cmd输入:node回车,就可以开始敲你的"js"代码
(2)、脚本/文件模式 - 正式开发中
  • 1、先创建xx.js,里面书写自己的代码
  • 2、打开cmd输入:node 文件的绝对路径
(3)、编辑器越来越强大了:安装插件,前提:至少两个方式能够成功,才可以安装插件
  • vscode - code runner:对着文件出右键,第一个选项就是code runner,或者 右上角有一个开始按钮

6、Node.js知识:

1、js和node的区别
  • 相同点:都可以使用一切的ECMAScript的东西包括一切的API都可以使用,在服务器端不存在任何浏览器,所以不必担心兼容问题
  • 不同点: 1、JavaScript:DOM+BOM - 做特效
    2、Node.js:虽然没有DOM+BOM,但是他却又10万以上+的模块等待我们学习
2、模块(module):每一个xx.js文件,都可以称之为是一个模块
  • (1)、模块化开发:如果以一个网站来说,我们可以按功能分为很多模块:商家模块、商品模块、促销模块、用户模块、产品模块....分工合作:将每个模块交给对应的人,完成,最后再由【主模块】进行引入
  • 1.每一个模块都有一个操作,可以用于公开/暴露自己的成员
    exports:Node.js自带的一个预定义变量,可以直接使用,是一个对象,放在此对象里面的东西,就是允许公开的东西

语法:
1、exports.属性名=属性值;
2、module.exports={ 属性名:属性值, ... }

错误导出法:
	exports={
		name:"袍哥",
		age:18,
		hobby:"学习"
		}
		
  • 2、每一个模块(主模块)都有一个操作,可以用于导入/引入其他模块
    require:Node.js自带的一个预定义变量,可以直接使用,是一个函数,函数中需要书写出引入模块的路径
    语法:var x=require("./文件名")

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

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

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

  • Node.js最大的特点:
    1、快 - 以前最快的是php,js的速度是php的十六倍,原因:因为官方提供的东西少,甚至连数据库的操作API都没有提供的;使用了chrome浏览器的v8引擎 .

1、官方模块

不需要下载,在你安装node.js环境的时候就已经带上了,但是某的模块可以需要引入,某的模块可能不需要引入:

1、Global模块:不需要引入

提供了:
	1、五个预定义变量,可以直接使用
                1、__filename - 获取当前文件完整的绝对路径
		2、*__dirname - 获取当前文件绝对路径,不包含文件的名字
		3、*exports - 空对象,可以用于公开暴露自己的成员
		4、*require - 函数,可以用于导入其他模块
		5、***module - 指代当前模块本身,甚至包含着以上4个操作
	2、定时器(周期性、一次性、瞬间定时器):定时器不是当初的js,只不过用法和当初一摸一样
	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("网址",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,()=>{
                console.log("写入完毕后,要做什么,必须放在这里面");
	        })//会替换掉原来的东西
					
异步追加文件:fs.appendFile("文件路径","新内容"/buf,()=>{
                console.log("写入完毕后,要做什么,必须放在这里面");
		        })//会替换掉原来的东西

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

mongo数据库

mongo==>基于json的数据库,json==>JavaScript Object Notation

1、mongo的安装&启动:

(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.dropDatabase();//一旦删除不能恢复,不推荐,因为要坐牢

2、数据表的操作

(1)、创建数据表:一定要先创建数据表后,我们才能查看到自己创建的数据库

db.createCollection("表名")//无限
db.createCollection("表名",{size:5242880,capped:true,max:5000})
//最大存储空间为5mb,最多存储500个,意味着这个数据表做了限制,不推荐

(2)、查看目前所有的数据表:db.getCollectionNames();

(3)、删除数据表:db.表名.drop();

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

(1) 增:db.表名.save({键值对,...})//一次只能插入一条数据

db.表名.save([{},{},{},....])//一次插入多条数据
//eg:
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就是你的查找到的结果
		})
//目前:前端能传到后端的技术,只有一个:form表单
//action属性可以随便自定义一个路由名称,后端解析此路由就可以通过objUrl.query.键名得到想要的部分