JavaScript的相关知识与问题

最初的样子

一, 不理解的知识
	1. 高阶函数'

一,JS的基础

1.查看效果,审查元素-Console
2.声明变量必须使用var关键词
语法一
	var name;声明变量,uname默认值为undefined
	name="佩奇"; 给变量赋予值
	console.log(name); 将该值输出
	const  声明一个常量,无法被改变
语法二
	var age=20; 声明变量为数值类型,颜色为蓝色
	console.log(age); 输出该数值
	var age="20"; 加上""/''后直接为字符串类型
	
三要素(输出方式)
	1.对话框(浏览器弹窗提示的内容)
		alert("傻逼");
	2.控制台输出 (常用)
		console.log("傻逼2号");
	3.在页面上输出  文档-输出 (输出到页面上的内容,也就是正常敲代码)
		document.write("你好 <h1>飞机<h1>");
	4.对话输入框(浏览器弹窗输入内容)
		 prompt("啊哈哈哈哈");
1.什么叫JavaScript
	与网页进行交互的脚本语言,具有逻辑性
2.JavaScript的组成部分
	ECMAScript(欧洲计算机制造商协会),用于指定脚本规范
	DOM (文档对象模型) Browse Object Model
	BOM (浏览器对象模型) Document  Object Model
1,变量
1.使用关键词 var
	var= name; name的默认值是undefined  变量的命名
	anme="内容"; 给变量赋予值,是一个字符串类型
	console.log(name);输出值
2.命名规则
	只能是数字,字母,下划线,不能数字开头
	不能是保留字或关键字(第一期表格里有)
	驼峰命名法(大驼峰和小驼峰)
		var yourName="傻逼"; 小驼峰 变量和属性
		var YourName={
    
    傻逼}; 大驼峰用于对象
	严格区分大小写
	变量要有语义化,见名思义
数据的类型,61.未定义类型
		var name undefined未定义类型
2.string 字符串类型,在任何字段上添加''/""可直接变成字符串
		var name="刘德华"
3.number 数值类型,也就是数字
		NaN 属于数值类型,但不是一个数值,为了程序出了错还能继续往下走的一个特殊值
		isNaN(num):判断是不是数值,是数值,返回false,不是数值,返回true
4.boolean 布尔函数类型(计算结果是对还是错)
		var flag=true()  flag=false()
		(e表示法) 1.2e9:后面增加90       1.2e-6:前面增加60
5.null 特殊数据类型 空类型,表现为灰色
		var obj=null;  null属于object(对象类型)
6.undefined 特殊数据类型 来自null,值相等
		null==undefined  都表示空
7.object 对象类型,表现为一个大括号  (包含Array数组 )
		var obj=new object{
    
    };
数据类型的转换
//1.强制转换,例子:其他五个转boolean类型
	1.boolean();语法结算时添加
		var name="内容";
		console.log(Boolean(内容));   //第一个字母要大写
	2.object转boolean         结果始终是true
	3.null转boolean           始终是false
	4.undefined转boolean      始终是false
	5.string转boolean         有字符串内容为true,没有字符串内容为false
	6.number转boolean	     非0数值都为true,0false

//2.类型转换
	1.Number();   //字符串转数值
		Number(str)
	2.parseInt();   //保留整数,不具备四舍五入(也可以字符串转成数值)
		var str="10.222";
		console.log(parseInt(str));   运算的结果会是10
	3.parseFloat();  //默认保留小数点(也可以字符串转成数值)
		var str="10.222";
		console.log(parseFloat(str));   运算的结果会是10.22
		console.log(str.toFixed(2));  运算的结果会是10.22,且变成字符串
	4.Math.round()  //四舍五入(可吧字符串转成数值)
		var str="10.522";
		console.log(Math.round(str));   运算的结果会是11
	5.toString();   //把数值转化成字符串( 可解析二进制乱码 )
		var num=200;
		console.log(num.toString())
自动转换  除了 + 都能自动转换(因为+号会出现拼接效果)
	var str="100"
	console.log(typeof(str))  结算为字符串类型
	console.log(Number(str))  强制转换为数值类型
		console.log(str*1/1-1)    在原数值上加算  可以为*  -  /
算法结果
	用typeof结算该值属于什么类型
		var name;
		name="小猪猪";
		console.log(typeof(uname));
数学算数运算符
	var num1=200;
	var num2=300;
	var num3=num1+num2;
	console.log(num3);  结果为500
	特殊的符号 % 用来运算余下的数值
		例子:var num=500;
			console.log(num % 60)  结算为秒(分需要下一个算法)
			console.log((num / 60) % 60)  结算为分(时需要下一个算法)
			console.log((num / 60 / 60) % 60)  结算为时
			
			
			

二,运算符和进制

1.  name.toString(16)把name数值转换为16进制
		name.toString(16) 	//转成16进制 根据括号内的数值选进制
		name.toString(8) 	//转成8进制
2.  parseInt(name,8)把指定数值进制转成10进制
		parseInt(name,8) 	//8进制转10进制
		parseInt(name,2) 	//2进制转10进制
,算数运算符
	+  -  *  /  %
	字符串和数值之间运算,字符串为数字会变成数值,字符串和字符串运算,会转数值算,+号例外
	%取余数
		例子:1500分钟数值,一天24小时,就是160,取余数就是60分
二,字符串运算符
	+
	 字符串和字符串/字符串和数值,利用+号会直接拼接都成为字符串
三,一元运算符 (对目标进行运算  操作一个值)
	++  num++   先取值,后运算
			++在后面,代表还没有+1,下一个值加上1
		 ++num   先运算,后赋值
		 	++在前面,代表先+1,成为下一个值
	--  num--   先取值,后运算
		--num   先运算,后赋值
四,关系运算符 (把目标进行对比)
	==  >  <  >=  <=  !=  !==  ===  运算结果都为true/false
	!=不等于    !==不全等于   ===全等于(指所有类型)
    比较公式
    	数值与数值比较       根据运算符比
    	数值与字符串比较     字符串为数字会转为数值比较
    	字符串与字符串比较   取左边第一个数字,十进制比较(ASCII表进行比较),逻辑运算符  (true1   false0)
	&&1==1 && 1==2 有一个是false,就是false,必须两个都是truefalse,找到后就取该值,未找到取最后的值
	||1==1 && 1==2 有一个是true,就都是truetrue,找到后就取该值,未找到取最后的值
	!  非 	为false,返回truetrue,返回false
				相反的意思
六,赋值运算符
	+=  -=  *=  /=
	例子:num += 1   结果为  num=  num+1,位移运算符
	<< 左位移   >> 右位移
	算法:先把一个值转化为2进制,再向左或者右移动n位,再转换为10进制来计算
	例子:  2 >> 2 = 0       2 << 2 = 8,三元运算符(三目)(在只有两种结果的算法使用)
	? : 
	例子:var = 1 > 2 ? 答案1 : 答案2
	解析:1是否大于2   大于为答案1   不大于为答案2
	
	
1.分支运算语法/Math
.固有程序三大流程控制
	1.顺序:浏览器解析顺序,从上到下,从左到右, = 会改变从右到左
		bar num = 10;   //10赋予给了num,所以=是从右到左
	2.分支:单分支,多分支
	3.循环:while , do..while , for , for..in,for..of,forEach,map等
		while , do..while , for用的比较多
		
二,单分支的语法(表达式运算,true执行第一个,否则执行第二个)
		if(表达式){
    
    正常执行} else{
    
    否则执行}
	1.多分支写法
		if(表达式){
    
    执行} else if(表达式){
    
    执行} else{
    
    }
	2.嵌套写法
		if(表达式){
    
    if(表达式){
    
    执行}else{
    
    执行}} else{
    
    执行}
		注意:只能嵌套在if里面,不能嵌套在else里面
	扩展:
	整Math.random()  该命令是取0-1中间的值,不包含1
		Math.pow(2,3); 	//2的三次方
		Math.PI;  	    //π的数值
		Math.abs(); 	// 返回一个值的绝对值,正数依旧为正数
		Math.pow(2,3)   // 2的3次方
		Math.max()  //一组数中,得到最大值
		Math.min()  //一组数中,得到最小值
		Math.round()  //四舍五入
		Math.ceil()		//天花板函数,向上取整   0.1取1
		Math.floor()	//地板函数,向下取整	 0.1取0
		2**3  代表次方  2的三次方
三,逻辑分支
	switch(表达式name){
    
    
    	case "内容1":                //输入的内容,就输出下面的输出内容
    		console.log("输出内容")   //逻辑代码,输出的内容
            break;                   //返回
        case "内容2": 			
            console.log("输出内容") 
            break;
        default:                     //不为上面的内容则执行
            console.log("你是傻子")
            break;
      }
      例子1:
      	var name = prompt("输入的内容"); //接收到的结果是字符串(prompt为弹窗输入内容)
        switch (name) {
    
                    // name对应输入的内容就执行(这里表达式为固定值)
            case "A":					//输入的内容
                console.log("80-100");	//打印的内容
                break;
            case "B":					//输入的内容
                console.log("90-100");	//打印的内容
                break;
            default:                    //不为上面的内容则执行
                console.log("一边玩去");
                break;
        }
        例子2:
          var grade = prompt("考试成绩"); //接收到的结果是字符串
          switch (true) {
    
                    //填true确认对错
            case (grade >= 80 && grade <= 100)://输出对错,结果为对
                console.log("A");//打印的内容
                break;
            case (grade >= 60 && grade <= 79):
                console.log("A");
                break;
            case (grade >= 0 && grade <= 159):
                console.log("B");
                break;
            default:
                console.log("一边玩去");
                break;
        }
2.循环运算
一,循环代码
	while  (先判断,后执行)
		语法: while(表达式){执行代码}
			表达式是否成立,成立则继续执行代码,不成立结束循环
			例子: while(name < 100){name++} 每执行一次,name+1,name数值为100时停止
	do...while (先执行,后判断)
		语法: do{执行代码}while(表达式)  先执行一次命名,再进行运算是否成立
	for  (用的比较多的)
		语法:for(循环值;循环条件;循环量增减){执行代码}
			循环值可不写,放在外面,另外两个必须写,分号; 必须存在
			执行顺序: 确认循环制-循环条件-执行代码-增减-循环条件~~~
			例子:	var num=0;
				 for(var name=1; name<100; name++){num+=name}
				 console.log(num)  //结果为1-100之和
	循环规则: 循环可以互相嵌套,短循环在外层(计算次数少),长循环在内层(计算次数多)
	结束循环: break; 该值在什么循环内,执行该值结束这个循环
	返回循环: continue; 该值在什么循环内,执行该值,结束本次循环,下一次循环开始,
		break; 跨级结束循环: 给一个循环值添加锚点,break;指定当前锚点,执行时结束锚点的循环
		例子: aaa: for(){} //aaa:为添加锚点
			  break aaa;  //结束aaa这个锚点 (可添加在任何地方)
二,合数和素数
	合数:能被自己以内的其他数整除,不包括0和1和2   比如: 4 6 8 9 10 12 14 15
	素数:无法被自己以内的其他数整除,不包括1和本身  比如: 3 5 7 11 13 16

三,函数

, 什么是函数
	1.将一段代码片段,抽取出来,成为一个独立的代码,叫函数,简称就是将一段代码打包
		用函数打包一段代码,输出函数则执行函数里面的代码
	2.函数=工具(方便,高效,无需关注原理,不受限制,方便维护)
	3.函数分内置函数,系统函数 (现有的)
		自定义函数 (重点)  语法:
		function name(){
    
     return;}  //name()函数命名-大括号接收实参-return;结束且输出函数
		name(); //调用这个函数,若括号内有值,对应形参,可自己调用自己
		注意:上面的name叫形参,,,下面的name叫实参
二, 为什么学习函数
	1.提高编程效率,降低难度
	2.可以把多个相似的计算式,合成一次,赋予一个计算的值,进入到函数里面计算,再输出这个值的答案
三, 什么是arguments(数值组合),只在函数出现
	1. 是一个数组,包含多个数值,按顺序排列
	2. 它是一个只能在函数内部出现的一个元素,不是真正的数组
	3.多个值运算的时候,不需要定义多个值,用该值接收
	4.接收实参给的数值个数,,,代替了形参(不需要在形参命名多次)
	语法:  arguments.length(代表实参的个数)
		  arguments[name] (取数值包里面的第几个数值)
		  arguments.callee
	例子:
		function fn(){
    
    
			var sum = 0;
			for (var i=0; i<arguments.length; i++){
    
    
				sum+=arguments[i];
			}
			return sum;
		}
		console.log(fn(10,20,30,40,50,60)); //结果为这些值的和, 函数里面的this
	函数的this默认指向上一级,上一级没内容就是window,上一个函数是window,里面的也是window
	改变this指向,给函数添加new,变成构造函数,改变函数的指向, 1: show=new fn()  2: (new fn()), 函数递归
	函数自己调用自己,但是必须要有临界点,结束标签,不然会进入死循环
	
五, 构造函数
	构造函数,在调用的时候采用new 调用,  var show= new show("aa")   没有用new调用就是普通函数
	构造函数里面的this默认指向函数本身
	
六, 匿名函数
	把函数赋予给一个变量,这个变量就是这个函数
		语法: var aa=function(){
    
    };  aa();调用函数
		语法: (function(){
    
    })(); 不需要调用,直接运行
	普通函数中可包含匿名函数,把匿名函数return给普通函数
		语法: function aa(){
    
     return function(){
    
    } };   aa()(); aa函数中的匿名函数
		
七, 回调函数
	一个函数,当做另外一个函数的参数,并在另外一个函数里面执行该函数,并且传递参数
		主要用来获取到正常外面获取不到的函数里面的值
		例子: function show(callback){
    
        //show形参接收一个函数
				setTimeout(function(){
    
       //设置一个定时器函数
				var aa={
    
     name="牛逼" }    //定义一个对象
				callback(aa)             //调用外面传进来的函数,传一个实参
				},5000)
			}
			var fn(abc){
    
    console.log(abc)}   //外面创建一个函数
			show(fn)                        //show实参传一个函数
	
1.事件驱动
,配合页面进行事件驱动
	1. 在页面代码上添加一个按钮,比如添加一个按钮,命名一个id
	2. 在js里面获取页面的元素:	
		var aa =document.getElementsByTagName("标签名称")[下标]  // 无兼容问题
		var aa =document.getElementByClassName("样式名称")
		var aa =document.getElementByName("属性名称")
	
		var aa =document.getElementById("id名称")  // 无兼容问题
		var aa=document.querySelector("#id名称")   获取一个按钮    H5新增,class.,纯标签不加
		var aa=document.querySelectorAll("div获取全部标签")		H5新增
	3. 点击后,触发一个js运算命令:
		name.onclick =要运算的命令
	4. js里面 name.value 可以获取这个id的值
	例子:
		<button id="btn">一个按钮</button>
		var aa = document.getElementById("btn");
		aa.onclick = num
		function num(){
    
    
            alert("你TM点到我了");
        }
     5. 引入外部JS文件  <script src="文件地址"><scipt>

四,数组

,什么是数组
	1. 他是一组数据,他里面的元素的类型不受限制
	2. 可以一次性装多个值,不受类型限制,可以随意扩容
二,数组的创建
	方式一: var arr=new Array(); 数组的构造函数
	方式二: var arr= Array();
	方式三: var arr=[]; (推荐使用),针对数组的属性
	1. length 判断数组里面有几个元素
		console.log(arr.length);  //判断数组里面有几个元素
		arr.length=3;  //把数字的个数,改成3个,只能减少,不能增多
	2. 数组的取值(下标)
		取值排序,0开始,往后依次  
		console.log(arr[1]);   //打印数组第二个值
		arr[3]="ZZ";  //修改数组里面第四个值
	3. 数组的删除和增加
		push()     //添加一个元素到最后一个位置,并返回数组新的长度
		pop()      //删除最后位置的元素,并返回被删除的元素
		unshift()  //添加一个元素到第一个位置,并返回数组新的长度
		shift()    //删除第一个位置的元素,并返回被删除的元素
			语法: arr.push("新元素");   name = arr.pop()
	4. 其他额外属性
		some()  //查找数组中的元素是否满足指定条件,有就返回true(不会检测空数组,不改变原始数组)
			语法: arr.some(function(ele,index){
    
     return ele>=10; })    ele代表arr里面的值
		every()  //查找数组中是否满足指定条件,有一个不是就返回false
			语法: arr.every(function(ele,index){
    
     return  ele>=10; })
		sort()  //排序,默认从小到大,只能10以内的数字比较,不能多位数,多位数比较的第一位数的ASICC值
			解决办法:添加一个函数(1表示交换位置,,-1不交换位置)
			语法: arr.sort(function(a,b){
    
    return a-b;})
		reverse()  //倒序,将数组里面的元素,倒过来排列
			语法: arr.reverse();
		concat() //合并数组,不会改变原来的数组,返回一个新的合并了的数组
			语法: arr.concat(arr1,arr2);
		join() //把数字变成字符串输出,返回一个新的字符串,默认逗号隔开,不影响原数组
			语法: arr.join();   arr.join("/"); 把逗号改成/slice() //截取开始位置,到结束位置的元素,不包含结束位置,进行取出来
			语法: arr.slice(0,2); //截取第一个到第二个位置的元素
		splice() //删除开始的位置计算,到后面的元素
			语法: arr.splice(2,1); 从第三个开始,删除一个元素
				 arr.splice(2,0,"aa"); 第三个元素,前面插入aa, 0为插入  1为替换
		for..in  //遍历循环,读取一遍数组里面的所有元素  (会遍历到原型上的属性和值,方法)
			语法: var arr = [11,22,33,44];
				 for (var i in arr){
    
        //i会遍历一遍所有属性
                    console.log("下标" + i);  //输出这是第几位
                    console.log("值" + arr[i]); //输出第几位的值
                    console.log( arr[i]);  //全部输出,
                }
		

五,字符串

, 什么是字符串
	1. 就是有 双引号或者单引号 包起来的就是字符串
	2. 他是JS里的一只数据类型 String
二, 字符串的创建方式
	1. var str="字符串"
	2. var str=String("字符串")
	3. var str=new String("字符串")  //字符串对象的包装集, 字符串的属性
	1. length  字符串的长度(只能获取长度,不能修改),字符串具有恒定性,万年不变
四, 字符串的其他属性
	charAt[]     //他的作用等价于[index]取值 arr.charAT[1]  //取某个下标的值
	charCodeAt() //获取下标的ASCII码    arr.chaCodeAt(1)
	String.fromCharCode() //把ASCII码解析为字符   String.fromCharCode(str)
	concat()    // 合并字符串,返回新的字符串  arr.concat(arr1)
	indexOf()   // 查找指定字符串第一次的位置,找到了返回下标,找不到返回-1
		语法: arr.indexOf("牛","3")  从第三个下标开始找,可不加
	lastIndexOf() //查找一个值最后出现位置的下标  arr.lastIndexOf("a")
	search()      //查找一个值最先出现位置的下标      arr.search(a)
	replace()     //替换,将一个值换成另一个  arr.replace("第一个","第二个")
		`注意: /\*/gi(/*代表符号,g代表全部匹配,i代表忽略大小写)
			  /^\s/   /\s$/   ^代表前面的    $代表后面的`
	substring(1,3) //截取一段下标字
		语法: arr.substring(1,3)  一个值的时候从0开始,可以负数
	slice     //截取开始位置到结束位置
	substr(2)    //截取开始位置到后面的个数
	split()     //根据分隔符,将字符串切割成数组  arr.split("=")
	trim()      //去掉前后空格     aee.trim()
	toLowerCase()  转小写   arr.toLowerCase()
	toUpperCase()  转大写

六,日期/时间

, 时间的创建
	1. var data = new Date(); 
	2. 获取: getDate() 获取当前日期    setDate() 设置当前日期
二, 可获取的值,改变Date即可   语法: date.getDate()
	FullYear()/年份	  Month()/月份(获取本地需要+1)	 Date()/Day()/星期		  Hours()/小时				 Minutes()/分钟
	Seconds()/Milliseconds()/毫秒		  Time()/1999年到现在的毫秒
三, 计时器
	setInterval("执行内容",时间(毫秒))  //定时器: 每隔一定时间,执行一次(不准时)
	setTimeout("执行内容",多久后执行(毫秒)) // 延时器: 多久后执行一次
	clearInterval(定时器ID);  //暂停某个计时器,也可以根据顺序填第几个
	clearTimeOut(定时器ID);  // 暂停某个延时器
		例子:
			ID = setInterval(function () {
    
    
            	console.log("阿福SaaS是打")
        	}, 1000)
     计时器的重启: 给计时器定义一个名字,后面名字=计时器可以重启某个计时器

七,对象

, 对象的创建方法
	方式一: var obj=new Object();  //这种方法用等于号隔离
                        obj.nam="老吊";
                        obj.age="21";
                        obj["age"]=22;  有双引号不是变量,没有就是变量
                        obj.ff=["你","我","他"]  //第一种方法写法
                        obj.gg=function(){
    
    }
                    console.log(obj.age);
	方式二: var Obj={
    
         // 这种方法用双引号隔离
                  name:"老吊",
                  age:20,
                  "aa":"19"
                };, 对象的输出
	方式一: console.log("我是是" + this.age)  //this就是对象的名称
	方式二: run.printInfo=function(){
    
            //run是对象名称   printInfo可以为任何值
			 console.log("我是是" + this.age)
			}  
			obj.run(), 对象的操作
	delete obj.name    删除一个属性或者方法
	obj.name和obj["name"]  是一样的,obj里的某个属性

八,BOM的属性

window对象有:  document/文档对象   history/历史对象   location/地址信息   frames/框架内容   				  screen/客户端显示屏幕信息       navigator/访问者有关浏览器的信息

一, window对象方法 语法: window.alert("")   可不加window
	1. alert("这是一个弹窗")
	2. confirm("这是一个确定和取消窗口")
	3. prompt("请输入一个内容")
	4. open("http://www.baidu.com","_new")  //自动打开一个网页,会被拦截,第三个属性为尺寸位置
	5. close();     //关闭浏览器本页面
	6. print();     //调出打印对话框
	7. window.location  //加载当前页面控制台信息
	8. 定时器的设置和移除
	
二, 页面信息互传的一个方式 (点击事件触发)
	1. 使用open和opener,可以获取到子页面的元素
			向子窗口发送 window.open('地址','打开方式','窗口大小')   //可以定个变量等于这个窗口
			窗口向父窗口发送 window.opener.父窗口的input标签来接收传的值

			父传子,定义一个空元素,接收要打开的一个新窗口,http开头
	2. 窗口打开  open('地址','窗口命名/方式','窗口尺寸'), location的对象属性 (文档加载相关信息,和导航) (点击事件触发或者打印)
	1. decodeURIComponent(str)   //对汉字内容进行解码,吧乱码重新翻译回汉字
	2. window.location.hash = "#666666"; // 设置#后的字符串并跳转
	3. window.location.href = url;  // 页面跳转,跳转到其他url页面
	4. document.write(window.location.href)  //被跳转的页面进行接收信息
	5. 其他属性值
		hash: 锚点/读取页面     port: 端口号      host: 主机名: 端口号
		hostname: 主机名       href: 整个URL     pathname: 路径名
		search: 获取?后面的字符串
		
四, location的对象方法 (点击事件触发或者打印)
	1. window.location.reload();         重新加载本页面
	2. window.location.reload(true);     强制重新加载
	3. window.location.assign("http://www.baidu.com");    跳转到指定连接
	4. window.location.replace(“http://www.baidu.com”);   用新的连接替换现在的
	
五, history的历史记录对象属性  (上网的记录,历史记录) (点击事件触发或者打印)
	1. history.length;     //历史记录的个数
	2. history.back();     //后退
	3. history.forward();  //前进
	4. history.go(-1);    //-1代表后退   1代表前进   0代表刷新, navigator对象  (保存了浏览器的信息) (点击事件触发或者打印)
	1. navigator.userAgent;  查看浏览器版本信息
		appName 浏览器名称      appVersion 浏览器版本    platform 操作系统
	
	
1.元素节点
, 获取元素节点属性 ( 语法: aa.parentNode )
	1. parentNode  获取最近的父级关系节点        
	2. nextElementSibling     //获取下一个兄弟关系   ie 6 7 8 有兼容问题!
	3. nextSibling            //获取下一个兄弟关系   非 ie 6 7 8 有兼容问题! (去掉了Element)
	4. previousElementSibling  //上一个兄弟关系---有兼容写法
	5. firstElementChild       //获取父级里面的子元素第一个---有兼容写法
	6. lastElementChild        //获取父级里面的子元素最后一个---有兼容写法
	7. childNodes.length       //获取父级里面的全部子元素,但是包含空格,需要用遍历挑选元素节点
	8. children.length         //获取父级里面的全部子元素,但是包含注释,谷歌没问题
		`兼容的写法: var name = id.nextElementSibling || id.nextSibling;`, 扩展内容
	1. name.nodeType  //判断name是个什么节点
		1 为元素节点      2 为属性节点     3 为文本节点
	2. name.nodeName  //判断name是一个什么标签
		元素节点返回标签名(标签名大写)      属性节点返回属性名称  其他节点返回
		
三, 元素的互相添加
	1. var div = document.createElement("div");        //创建一个div元素节点
	2. var Txt = document.createTextNode("这是文本");    //创建一个文本节点
	3. name.appendChild(子级id);                    //把一个子级添加到父级最后一个
	4. name.insertBefore(子级id, name的前面)         //把一个子级添加到指定的前面
	5. name.className = "box"                      //给一个name创建一个class属性
		`特殊: document.body      代表页面里面的body`
	6. name.removeChild(子级id)             //删除父元素里面的一个子元素
	7. name.remove()   //直接把name这个元素标签删除, 元素标签固有属性节点操作 (比如 <a src"" class"" >)
	1. name.attributes;                 //获取到所有的属性,后面加括号,判断这个属性是什么节点
	2. name.getAttribute("");           //选择一个属性名称,获取其对应的属性值
	3. name.setAttribute("属性","值");   //赋予一个标签新的属性和值
	4. name.removeAttribute("属性名");   //移除一个属性值, 克隆一个元素标签
	1. div.cloneNode(false);  //浅克隆: 只克隆div当前的结构
	2. div.cloneNode(true);   //深克隆: 克隆div的全部属性, 替换一个标签
	1. name.replaceChild(div,box);     //name里面某个标签替换成另一个标签(需要创建出来)
		`特殊: 如果是两个存在的属性,互相替换,原有的属性会消失,div是新表情,box是被替换的`, 页面表示
	nam.innerHTML= ;  //获取一个标签里面的所有内容,包括标签里面的标签全部内容---也可以插入
	nam.innerText=""; //获取一个标签里面的文本内容---也可以插入
	nam.nodeValue=""; //文本节点使用会输出带标签的内容
	bb.style.width= "";  //获取某个标签的样式属性,这里是CSS属性的宽度

九, 事件

, 鼠标事件
	1. onclick       //单击触发事件
    2. ondblclick    //双击触发事件
    3. onmouseenter  //鼠标移入触发事件
    4. leave  //鼠标移出去触发事件
    5. move   //鼠标在里面移动就触发
    6. over   `特殊移入事件,移动到子元素也会触发`
    7. out    `特殊移出世界,移出到父级元素也会触发`
    8. down   //鼠标按下不松开触发
    9. up     //鼠标松开的时候触发
    10.wheel  //滚轴按钮按下触发
    11.oncontextmenu   //鼠标右键按下时触发  需要去掉默认的右键菜单
    	兼容写法:  if (e.preventDefault) {
    
            //去掉右键默认菜单 
        			 e.preventDefault();
            		} else {
    
    
               		 e.returnValue = false;
            		}
    12. ele = e.target||e.srcElement;  //ele来获取点击的目标是什么,需要先获取鼠标节点
    		ele.nodeName   //判断点击的是什么标签,默认大写
    		ele.className  //获取被点击里面的class名字, 键盘事件
	onkeydown    //当按下键盘上的键触发,一直按着会重复触发
    onkeypress   //当按下键盘上的字符键触发,一直按着会重复触发
    onkeyup      //松开按下的键触发
          扩展: e.keyCode;   //把按下的键转换为编号  需要先获取键盘按下节点
               String.fromCharCode(e.keyCode);   //把编号转换为字母
               e.key   //输出的为小写
    组合键事件
    altKey       //按下alt键  , 结果为true
    shiftKey     //按下shift键
    ctlKey       //按下ctrl键
    metaKey      //按下window键
    keyCode      //获取键盘上任何一个键的ASICC码(不分大小写)
    charCode     //获取键盘上任何一个键的ASICC码(分大小写), HTML事件  -跟页面相关的触发事件
	语法 window.onload =    //被触发的对象是页面
    onload       //页面加载完成后触发
    onunload     //页面完全卸载后触发(刷新清除了前面的内容)
    onselect     //选中指定文本里面的内容时触发 (比如input对话框)
    onchange     //改变指定文本里面的内容时触发 (比如input对话框)
    onfocus      //当页面或者元素获得焦点时触发 (鼠标的光标)
    onblur       //当页面或者元素失去焦点时触发 (鼠标的光标)
    onsubmit     //当点击提交按钮时在元素节点上触发 (比如提交<form>表单)  //点击优先级高
    onreset      //当点击重置按钮时在元素节点上触发 (比如重置<form>表单)  //点击优先级高
    onscroll     //当用户用滚轴滚动滚动条时触发   后面加Top为不可见区域的高度
    	扩展: window.scrollTo(x,y) 为滚动条的x轴和y轴位置(只写一个默认为X)
    	      getScroll().Top;    页面不可见区域的高度

    oninput      //当用户在输入的时候触发
    onsize       //改变窗口大小时触发
    	注意:  document.XXX= function(){
    
    兼容+执行命令}  为针对网页页面
    
四, 事件对象 event
	button    //判断获取鼠标按下时按的什么键
          0为左键     1为滚轴按钮     2为右键 
    扩展: 获取事件对象的兼容写法: var e=evt||window.event;    evr对应函数的形参
    扩展: 获取点击的是什么兼容写法: var ele = e.target || e.srcElement;, 鼠标点击位置定位 //可以填left/top/right/bottom
	clientX      //浏览器当前可视范围的X坐标    不加X/Y,加Width和Height获取可视浏览器宽度
			`window.innerHeight   获取页面可视区域的高度`
    clientY      //浏览器当前可视范围的Y坐标
    pageX/Y      //距离浏览器内容区域的坐标
    screenX/Y    //距离显示器屏幕的坐标
    offsetX/Y    //鼠标点击的元素位置距离元素边界的坐标   不加X/Y,加Left是元素到上一个元素边界的距离
    		     //加Width,是获取自身的宽度
1. 事件的冒泡
, 冒泡顺序,默认从里到外,逐个触发
	例子: 三个层叠的方块,点到最小的那个,也相当于点到其他的两个
	
二, 阻止冒泡时间的默认行为(点到最小的就停止了,不再往外走)  
	方法: 点击函数添加阻止事件
	var e = evt || window.event;
	 方法一:  (兼容写法)
          if (e.stopPropagation) {
    
          //阻止默认冒泡顺序的兼容写法
               e.stopPropagation();      //非IE使用
           } else {
    
    
               e.cancelBubble = true;     //IE使用
           };
	 方法二:(阻止浏览器的默认行为 //比如右键菜单)      
           if (e.preventDefault) {
    
          //阻止默认冒泡顺序的兼容写法
                e.preventDefault();      //非IE使用
            } else {
    
    
                e.returnValue = false;     //IE使用
            };
	 扩展: 给a标签阻止默认事件,可以添加一个点击函数,加入确认窗口confirm("确定跳转吗")
2. 事件监听器
一, 捕获事件  (捕获和委托,需要定义的同一个函数)
	box.addEventListener(“click”, func, false) 
		click: 事件触发条件,不带on
        func:  事件调用的函数名称,没有双引号也没有(),也可以直接在里面写函数
        false/true:  是否使用捕获,反向冒泡(默认为false),从内到外,改为true从外到内
        {capture:true, once:true}   第三个也可以为函数,前面的为是否捕获,,后面的为触发次数为一次
二, 移除事件
	box.removeEventListener(“click”, func)
	移除事件监听器,只能删除用该方法添加的事件监听器 (IE8以下不支持)
	
三, IE8以下使用的事件监听器
	 box.attachEvent("onclick", fn);   //添加事件,需要加on
     box.detachEvent("onclick", fn);   //移除事件
     
四, 两者的兼容写法 (封装兼容)  
	添加事件: obj为捕获和阻止按钮 - 后面三个为固定
	function addEvent(obj,type,callback,useCapture){
        if(obj.addEventListener){
            obj.addEventListener(type,callback,useCapture)
        } else {
             obj.attachEvent("on"+type, callback)     //兼容IE的需要加on  后面的固定
         }
      }
      捕获调用: addEvent(box,"click", fn);    被点击的内容 - 触发条件 - 触发的内容
	
	 阻止事件:
	 function addEvent(obj,type,callback,useCapture){
        if(obj.removeEventListener){
             obj.removeEventListener(type,callback,useCapture)
         } else {
             obj.detachEvent("on"+type, callback)
         }
      }
       捕获调用: removeEvent(box, "click", fn);    点击触发的内容 - 事件名称 - 触发的内容
3. cookie
一, cookie的作用
	1. 作用就是为了在浏览器,存储少量数据,并且随着请求携带数据到服务器
	2. 缺点: 最大储存为4K - 且不能存储敏感数据 - 容易被伪造和挟持
	
二, cookie的完整格式语法
	"name=value;expires=date;path=路径;domain=域名;secure;"  每个用; 隔开
		name=value   两个都可变,你要保存的名字,值(必填)
		expires="+date+"   cookie的失效时间,默认为浏览器关闭失效,date为获取的时间
		path=路径      存储的路径
		domain=域名    存储访问某个指定网站的cookie
		secure        安全设置, 设置了则必须使用https协议才可获取cookie(可选)
		
三, URI编码/解码设置cookie (内容必须为字符串)
	document.cookie = "user2=" + encodeURIComponent("张三");
		设置张三为一个URI编码,设置cookie的名字
	decodeURIComponent(document.cookie);
		对上面的赋值URI编码进行解析,结果为  user2=张三;
4. JSON
, 什么是JSON
	1. JSON是一种结构化的数据表示方式(数据格式)
 	2. 是一种轻量级的数据格式

二, JSON的写法
	普通对象的写法:  var  obj={
    
    name:"天堂",age:20};
	JSON字符串的写法:  var json='{"name":"天堂","age":100}'
		里面的内容都需要双引号,数值可不用加

三, JSON的作用
	1. 配置文件   2. 用于跨平台传递数据

四, JSON的转换
	JSON.stringify(obj);  把一个对象转换成字符串
	JSON.parse(str);    把一个json字符串的写法转换成对象/数组

五, JSON的方式创建数组和对象
	数组:  var arr=JSON.parse('[]')
	对象:  var obj=JSON.parse('{}')
5. 正则表达式
一, 什么是正则
	1. 匹配有规律的字符串
	2. 正则的特性-懒惰性: 找到一次就不找了,需要用g全局   贪婪性:
	
二, 正则表达式:  由元字符和修饰符组成
	语法: var reg=/ /;
		 var reg=new RegExp(/ /);
 	正则寻找值的时候,找到一个就不找了,后面加特殊符号: i 代表不分大小写  g 代表全局匹配  m 代表换行
 	
三, 字符串的正则表达式用法
	search(/帅/) 找到一串字符串中的这个字
	replace(/帅/g,'丑')  找到字符串中的所有字,并替换
	match(/帅/g)  找到一串字符串中的所有这个字,组成数组

四, 正则表达式常用的返回值
	test() 符合返回true   否则返回false
	exec() 符合返回数组   否则返回null
	
五, 正则的-元字符
	. 匹配任意字符      * 任意次数     .*任意字符任意次数
	+ 至少一次         ? 0次或1次     [] 取值范围 [0-9] [ab]a或b
	^ 开始位置         [^] 取反       $ 结束位置
	{n} 固定n次       {n,m} 最少n次,最多m次    {n,} 最少n次,最多不限
	
	\d 只能是数字,或者[0-9]       \D  不能是数字,或者[^0-9]
	\w 只能是数字,字母,下划线_     \W  不能是数字,字母,下划线_,或者[^0-9a-z_]
	\s 代表空白                  \S  不是空白
	 |  或者,其中一个符合即可      ()  进行分组,整体匹配,后面可加{5},找几次,要是一连串的
     \  转义,把元字符变成普通符号    ?: 非捕获,对(?:)分组其中一个,不进行捕获

十, ES5-ES6新增

一. 通用新属性 (不支持IE8及以下)
	"use strict"  严格模式,用来消除一些语法的不合理,更加严谨,安全,快速
		1. 不可以忽略声明var变量
		2. 在函数里面,会禁止使用this关键词指向全局
		3. 不能使用八进制开头,八进制(05555)
		4. arguments变量,无法被修改,只有在arguments内部被修改才行,外部修改实参无效
		
	bind()属性:  改变函数里的this指向,函数的this默认指向上一级或者window
		语法: 函数内 function fn(){ console.log(this.arr) }.bind(obj)
        		   fn()            //在函数结束处添加
        	 函数外 function fn(){ console.log(this.arr) }     
        	 	   fn.bind(obj)()  //在调用处添加
1. ES5 数组新增
indexOf() 在一个数组/字符串里面查找一个内容的下标,如果没找到下标就是-1
forEach() 遍历一遍某个数组,里面需要加函数来执行,没有返回值,对原数组没影响
	语法: arr.forEach(function(el,index,arr){执行})
			el: 数组里面的每一个数值
			index: 数值里面每一个数值的下标
			arr: 数组本身
			
map() 遍历一遍某个数组,里面需要加函数来执行,可以用return返回一个值,对原数组没影响
	语法: arr.map(function(el,index,arr){执行})
	
filter() 过滤出数组中你想要的元素,并返回,不改变原数组,需要定义一个值接收
	语法: arr.filter(function(el,index,arr){ if( el>20 ){ return el; } })
	     arr=arr1.filter(el){ return el>3 }
	
some() 查找数组中的内容,找到了,就返回true,后面的不找了,需要定义一个值接收
	语法: arr.some(function(el,index,arr){ if( el==20 ){ } })
every() 查找数组中的内容,需要全部符合,一个不符合,就返回false,后面的不找了,需要定义一个值接收

reduce() 非遍历的特殊值
	语法: arr.reduce(function(pre,cur,index,arr){执行})
		pre: 上一次的值,后面为undefiled
		cur: 当前正在处理的数组元素,没有return返回一个值给pre,就取后面一个
		index: 当前正在处理的数组元素下标
		arr:  再次调用该数组
		return pre; 返回一个值给下一个pre
	案列: 
		var arr = [11, 22, 33, 44, 66, 55, 22, 99, 33, 44, 55, 11]
        arr.reduce(function (pre, cur, index, arr) {
            console.log(pre, cur, index)
            return pre + cur;
        })
	
2. ES6新增
, ES6新增属性
	let 声明一个变量,var差不多,但是作用域只在块级里面,超出就失效
	const  声明一个常量,无法被改变,比如Math.PI是固定的圆周率
			
三, ES6数组方法
	Set()  结构类似数组,成员值都是唯一的,不会重复   [...new Set(arr)]  去重后输出为数组
		语法: set = new Set(arr)    console.log(set.size)
		输出语法: .size 下标个数   .add(9) 添加一个值   .delete(9) 删除一个值   
				 .has(9) 确认是否有这个值     .clear() 清除所有值
	Array.from() 把伪数组变成真数组,对象里面需要添加 length:3 来确定更改数组的个数
		语法: var obj = {
    
     0: "你大爷", 1: "你二爷", 2: "你二大爷", length: 3}   						 console.log(Array.from(obj))
	Array.of()  把任意一组值,转换成数组  比如: arr=Array.of(11,22,33,44)
	find()和findIndex() 获取数组里面每个对象的值,下标,内容 (用来查找元素)
		语法: arr.find(function(el.index.arr){
    
     if判断 })
			if判断: if( el==10 ){
    
     return el; }       (findIndex返回的下标)
			
	for..of    遍历数组和对象,字符串 (不会遍历到原型上的属性和值,方法)
		语法: for(var el of arr.keys()){
    
     console.log(el) }
		特殊: values    得到值    
		      keys      得到下标  obj[el] 打印值
		      entries   得到实例
	
	... 扩展运算符 (可直接把一个数组拆分成多个数值)
	Math.max/min   找一串数值中的最大值和最小值,需要用到...拆分数值	
		语法: Math.max(...arr)
		特殊: ...合并数组  arr3 = [...arr1,...arr2]  转化成普通数值合并

四, 箭头函数:  箭头函数只执行一行代码时,不需要return
	语法: var fn = n => n*100;   fn(2)    可以不写functionc  
		 var show = (n1,n2) => {
    
     return n1+n2; }  show(1,2)
		 	理解: n为形参   n*100{
    
    }里面要执行的内容
	扩展: 箭头函数里面的this,默认指向外面一层,非箭头的普通函数,默认指向window (或者.前面的一位), ES6的对象
	1. ES6 对象的简写: 在对象的外面进行赋值, 对象里面直接填入变量
			例子: var age=10;
				 var age1={
    
    age} 
	2. ES6 对象方法的简写: 直接方法后面添加(){
    
    }  不需要加function
			例子: var age={
    
    
					id(){
    
    }
			      }
	3. ES6 对象的其他属性
		Object.is(-0,0)    两个值进行比较,纯粹的外观进行比较,一样就是true,不一样就是false
		Object.assign()  对象的浅拷贝和合并(只拷贝对象的第一层数值,第二层,第三层两个对象共享)
			obj1 = Object.assign({
    
    }, obj)    //把obj拷贝给空元素,赋于给obj1
			特殊: 把第二个值合并给第一个,接收的第三个跟第一个相等,第二个不变,若第一个为空,两个不相等
		对象的深拷贝
			把对象转字符串赋值,再转对象赋值,得到全新的对象
	
	4. WeakSet  对象的去重,成员都是唯一的,不会重复
		语法: let ws = new WeakSet([obj1, obj2])
		输出语法: .size 下标个数   .add(age:20) 添加一个对象   .delete(age:20) 删除一个对象   
				 .has(9) 确认是否有这个对象     
	
	5. Map 是一个超对象,可以添加属性和方法  ,也不能出现重复的,属性名一样,前面的会被替代
		语法: map = new Map();     map.set("a", [11, 22, 33]);
		语法: var map = new Map([[1, 'one'], [2, 'two'], [3, 'three']])  添加方法
		
		输出语法: .size 成员个数   .set(9,6) 设置一个属性和值   .get(key) 读取一个值   
				 .has(9) 确认是否有这个值     .clear() 清除所有值      .delete(key)删除某个值
		
	6. assign 对象的拼接,把两个对象合体成一个
		语法: Object.assign({
    
    },obj1,obj2)  //把后面的跟第一个合并,后面的不会改变,第一个会改变
2. ES6 字符串新增
, ES6字符串方法
	indexOf("")    在一个字符串里面找某个内容,找到返回下标
	includes("")   判断字符串中是否有这个内容,找到返回true  第二个参数是从第几位开始找
	startsWith("")  判断字符串是不是这个内容开头,第二个参数从第几位开始找
	endsWith("")    判断字符串是不是这个内容结尾,第二个参数从第几位开始找
	repeat(100)     让一个字符串重复打印多少次
	``和${
    
    }        进行字符串拼接
		语法:    str1="牛"       str=`你很${
      
      str1}`
	
	//字符串的补全( 第一个参数:最低长度  第二个参数:补全的内容 )
	'x'.padStart(5, 'ab')    //x只有一个,所以会利用ab在开头补全至  ababx
	'x'.padEnd(5, 'ab')      //x只有一个,所以会利用ab在结尾补全至  xabab
	
3. ES6其他
解构赋值  用一个值去接收赋的值,需要对称,对象的情况下需要名字一样
		语法: var [a,[b,c],d]  = [1,[2,3],4]
		语法: var {
    
     name, age } = {
    
     name: "牛逼", age: 30 }
		
class 类对象,ES6新加入
		例子: class Person {
    
                         //设置一个父类函数
            	constructor(Name, Age) {
    
            //接收两个数据,形参
                	this.name = Name;           //把传进来的数据赋值
                	this.age = Age;				
            	}
            	run() {
    
     console.log('run') }   //新增一个方法                 
            	static say() {
    
     执行内容 }       //静态新增一个方法 需通过父类获取 Person.say  
        	}
        	var p = new Person('大佬','50');      //传两个数据进去,实参
        	console.log(p)
        	P.sayHi()                        //静态方法
        	
class 类对象的继承  extends
		class Employee extends Person {
    
                //定义一个Employee继承Person的方法
            constructor(Name, Age, Stu) {
    
    
                super(Name, Age)                 //继承前面已有的
                this.sut = Stu;                   //设置自己新增的
            }
            position() {
    
     console.log(this.name + "出来吃烤肉吧!") }  //子类新增一个方法
        }
        var E = new Employee('大佬', 50, '未知', 222)   //子类变成构造函数,传四个值
        E.run()                                      //输出继承的run方法
        E.position()								 //输出自己的position方法
        console.log(E)
        
Symbol 方法唯一 (两个一样的对象,只能存在一个)
		var s1 = Symbol("foo");    var s2 = Symbol("foo");     s1 === s2; // false
		
Generator 函数,可以对函数进行暂停
         语法 function * show(){
    
     yield }           //yield用来暂停此函数
         输出: show.next().value              //输出函数里面计算的内容
         注意: 如果使用了暂停,next里面的done为false
         
对象的克隆( 对象里面有对象,按层级分 )
		浅克隆:var obj1 = Object.assign({
    
    }, obj)  //只克隆第一层,后面的共享(改变一个都会改变)
        深克隆:把一个对象,通过JSON,先转字符串,再转对象进行赋值,两个对象互相不影响
                              
Promise 解决回调地狱和并发处理一系列问题,需要把Promise  return给外面的函数,方便下面再次使用
		语法: P= new Promise((resolve,rejected)=>{
    
          //两个参数,都是函数,一个是成功,一个是失败
                resolve("这是正确")                    //成功了就执行
            })
        
       	P.then((yes)=>{
    
    console.log(yes)} return P)    //then是接收正确和错误的参数
              得出结果后,可以再次调用函数,然后return出去,再用then看结果
                              
       //函数的写法
       `function show(path){
           return new Promise((resolve,reject)=>{
               进行一段指令
               resolve(data)
           })
       }
       show(aaa).then((data)=>{ 打印data } return show(aaa) ).then()``
4. 动画
一, 获取元素本身的一些属性
	box.currentStyle[top]    谷歌不兼容(为undefined)    获取元素距离上面的距离
	window.getComputedStyle(box,null)[top]     谷歌兼容  
	
二, 对获取属性进行封装成函数   ( box为元素本身,,attr为要移动的方向 )
	function show(box,attr){     //输出的尺寸带有单位,需要用parseInt( show(box,attr) ) 转数值
		if(box.currentStyle){ return box.currentStyle[attr]; }
		window.getComputedStyle(box,null)[attr]
	}
	
三, 获取鼠标滚动,页头( 内容 )不可见部分
	document.documentElement.scrollTop       //有标准的声明头,才生效  可简写为 scrollTop
	window.pageYOffset                       //最新的ie 9 10 11
	document.body.scrollTop                  //没有标准的声明头,才生效
	
	获取有没有声明头: document.compatMode     结果:CSS1Compat有   BackCompat无
	
四,  鼠标滚动获取兼容写法
	function getScroll() {
        if (window.pageYOffset != undefined) {           //它声明头无关,跟版本有关, ie 9以上
            return { left: window.pageXOffset, top: window.pageYOffset
            }
        } else if (document.compatMode == "CSS1Compat") {     //有声明头
            return {                                          
                left: document.documentElement.scrollLeft,
                top: document.documentElement.scrollTop
            }
        } else {                                          //无声明头
            return {left: document.body.scrollLeft,top: document.body.scrollTop}
        }
    }

十一, 面向对象

一, 什么是面向对象
		面向对象是利用对象进行编程的一种思想;  有称之为: oop思想
		面向对象编程(OOP)的三个基本特征是:封装、继承、多态
		封装: 将相同的属性和行为,封装一个独立的实例,称为类
		继承: 子类拥有父类的属性和方法,子类可以重写父类的方法,子类可以添加更多属性和方法
		多态: 重载, 在一个类中,有同名不同参数的方法(重载),重写, 子类重写父类
		
二, 工厂模式
		工厂模式就是把 var obj = new Object() 创建的对象包起来
1. 闭包
一, 闭包就是 函数嵌套函数,内部函数可以引用外部函数的参数和变量
		创造局部变量,函数内可以使用,外部使用不了,内部函数return出去,让外面可以访问,但是无法修改
		外部函数调用内部函数,需要再加一个 ()  例子: show()()
		可以设置一个常量,来防止被外面改变
		
二, 内存泄露,闭包没有内存泄露,内存泄露是指你用不到(访问不到)的变量,依然占据着空间,不能被再次利用

十二, Ajax

一, 什么是ajax: 与服务器进行数据交互的一种技术,实现同步和异步的局部数据刷新
		好处: 提高了用户体验 / 降低了压力 / 减少了浏览器的全局渲染
		Ajax主要用于数据的校验
		
二, 进程和线程
		 一个进程可以包含多个线程
		 	单线程和多线程
		 	单线程 --- 一次
		 	多线程 --- 多次
	比喻: 一家饭店就是进程,n个服务员就是多线程   '浏览器解析引擎'属于单线程,容易造成浏览器阻塞
1. 同步和异步
一, ajax的核心对象   XMLHttpRequest 简写 XHR
		function createXHR() {              //ajax核心对象(必写)
           if (window.XMLHttpRequest) {     //谷歌和火狐的兼容写法
               return new XMLHttpRequest();
            }
               return new ActiveXObject("Msxml2.XMLHTTP")  //IE的兼容写法
          }
          	
二, 同步和异步    是在浏览器解析引擎出现  
		同步false: 多件事情,按照顺序,一步一步执行
		异步true: 能同时处理多个事物,不会造成阻塞, 写法需要回调函数
		
三, 封装ajax函数 (主要获取到服务器返回的数据,也就是页面的内容)
		function Ajax(url){           //封装函数(必写) 形参还可加 对象/函数内调(callback)
			var xhr = createXHR();    //把核心对象赋值
			xhr.open("get", url, false);   //请求方式-链接-同步/异步,异步为true
			xhr.send(null);  //像服务器发送请求(get才用)  post请求给向服务器发送的参数(字符串)
			
			1. 同步判断接收数据
            if(xhr.status==200){ return xhr.response }  //接收的数据
		}
			2. 异步判断接收数据
			xhr.onreadystatechange = function () {         //用来获取readyState状态
                if(xhr.status==200&&xhr.readyState==4){    //判断服务器状态和数据响应状态
                    if(typeof (callback) == "function"){   //回调函数,判断第三个值是不是函数
                        callback(xhr.response) 
            }}}
    重点1: 异步接收数据,需要触发 xhr.onreadystatechange 事件,然后才能检测到readyState属性
	重点2: 异步需要回调函数,callback为Ajax第二个形参,传过来的是函数,,判断完后再调用函数,把内容传过去
	扩展: statusText/HTTP状态码的说明         responseText/返回纯文本
		 responseXML/返回xml的格式           response/返回的是状态的集合码
	
四, 接收的一些数据内容
		xhr.status响应的HTTP状态码
			200/服务器状态ok     304/缓存    404/找不到服务器     500/服务异常
		
		xhr.readyState异步响应的状态码
			0/未初始化     1/启动,已经调用open()        2/发送,已经调用send
			3/接收,部分已响应         4/完成,全部响应完成
			
2. 服务器查询用户名
一, 通过连接查看: "http://www.useker.cn/api/day22/checkname.php?regname="+this.value
		this.value为表单输入的内容
	
二, Ajax函数传三个数据接收
		function Ajax(url, data, callback) {       //获取连接,对象,执行函数
			let xhr = createXHR();                 //获取ajax核心对象
			xhr.open("get", url + "?" + getPramas(data), true)  //设置传递内容
			xhr.send(null)
			xhr.onreadystatechange = function () { 如上面正常判断且返回 }
	扩展: 
	注意: "http://www.useker.cn/api/day22/checkname.php" 网址后面都不要了,来进行拼接
			
三, php后面的对象拼接
		function getPramas(obj) { 
			var str = "";
			for (const key in obj) { str += key + "=" + obj[key] + "&" }
			return str; 
		}
	扩展: obj为一个对象,对象进行遍历,最后输出结果为  obj={regname:"刘德华"}
3. POST请求
一, 判断账号注册: url("http://useker.cn/api/server/login.php")
	JS代码:  
	function Ajax(url, date, callback) {   //链接-对象-函数回调
		var xhr = createXHR();             //获取ajax核心对象
		xhr.open("post", url, true)        //设置 请求方式-链接-异步
		xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //必填
		xhr.responseType = "json";         //返回的类型是json,否则文字为乱码
		xhr.send(getParams(date))          //send内填 对象转字符串拼接函数
		这里为上面正常的true异步判断接收数据
	}
	
二, 对象转字符串拼接
	function getParams(obj) {         //获取一个对象,对象的名字根据url端口是否写死
        var str = "";                 //创建空对象
        for (const key in obj) {      //遍历对象
            str += key + "=" + obj[key] + "&";  //字符串拼接   结果为: uname=大佬&
        }
        return str;                   //把拼接好的结果返回给函数
    }

十三, PHP

一, PHP初体验
		什么是静态页面: 以html或htm结尾的文件,就是静态页面
		什么是动态页面: 静态页面里面嵌套了其他后台语言的标记,并且后缀为 php  jsp  aspx  asp
		注意: 后缀为php的页面不能浏览器直接运行,要经过服务器的php编译码,编译成html再输出到浏览器
		
二, PHP写法  (每一行代码后面,都必须打 ; 分号)
		语法: <?php   (页面没有html代码的写法)      <?php ?>   (页面有html代码的写法)
		
三, 创建元素写法
		$ 声明变量   $uname = "刘德华"
		print_r()   输出元素到页面,类似console.log()       print_r( $uname )
		var_dump()  查看一个元素的类型,类似typeOf()         var_dump( $uname )
		 .  字符串的拼接方式,跟js里面的+一样
		 ->  什么里面的什么,跟js里面的.一样
		$arr = array("11",'22',33,true)     创建一个数组
		
四, php的一些方法
		$_REQUEST["uname"];  判断接收的数据是什么协议
			GET为get协议   POST为post协议    REQUEST为两个协议都行
		
		json_encode($Arr);    把php数组,转成json字符串
		json_decode($Arr);   把json字符串转成数组
		array_push($Arr,$Arr1);   合并数组,把后面数组的内容添加到前面的数组里面去
		file_get_contents("./users.json");   读取本地json文件里面的数组
		file_put_contents("./users.json",字符串);  把一段字符串文件,传到本地数据文件里面去
		
1. JSONP原型
一, 什么是原型: 元素就是一个函数中自带的一个属性 (构造函数)
		每个函数都有一个prototype,这个属性是一个对象
	扩展: show.prototype.constructor === show      prototype里面的constructor就等于函数本身
		
二, 原型的作用
		可以让同一个构造函数创建的所有对象共享属性和方法
		
三, 判断构造函数里的一个数值时私有还是公有
		show.hasOwnProperty(aa)   私有返回true  没有或公有返回false  (但是它不知道到底有没有该值)
		(aa in show)              有该值就返回true    没有就返回false
2. 继承
一, 继承方式
	原型继承,父类的属性不能在子类里面初始化
	对象冒充继承,bind,call,apply,利用这三个方法,改变父类的this指向
		bind   改版函数this的指向   show.bind( obj ) 把show函数的this指向改为obj
		call   继承一个函数的属性    show.call(this,Name)    继承show函数的属性,用逗号隔开
		apply  继承一个函数的属性    show.apply(this,[Name]) 继承show函数的属性,中括号,逗号隔开
		
二, 继承
	原型组合继承 == 原型继承 + 对象冒充
    寄生组合继承 == 寄生继承 + 对象冒充
     
    对象冒充    bind,call,apply                   //继承父类的所有属性
    原型继承    show.prototype = new DragBox()    //继承父类的所有方法   
    寄生继承    Object.create(base.prototype);    //继承父类的原型
    	Object.create(); 窃取别人原型对象
    
     

十四, Jquery

一, 什么是Jquery
		jquery是一个快速、小型且功能丰富的javascript库
		兼容多款浏览器, html文档遍历和操作、事件处理、动画和ajax
		三个版本 1.X/用于PC端    2.X//移动端    3.X/轻量级PC和移动端  
        jq实行同样的命令时,后面不会覆盖前面的
         
二, 过滤选择器  $("li>li").css() css值为带单位的,写单位需要加""   不写单位不加""  
		nth-child(2n)   子标签的奇数或者偶数,或者第几个
		contains('牛')  标签文本中包含该文字的
		has(span)       某个标签是否有某个标签,有就直接设置
		>/空格 某个标签里面的某一个        ~/+  除了自己,拿到所有的兄弟
		odd 拿奇数                      even 拿偶数
		first 选取第一个标签             last 选取最后一个标签
		gt(2) 下标大于某个数的子标签       lt(2) 下标小于某个数的子标签
		eq(2) 拿到第几个                 not(li) 除了li都拿到
		empty 文本为空的                 parent 最近的父级标签
		selected   下拉列表选中的
        checked    表单按钮选中的
		[name='uname']   属性选择器,可以选择任何标签符合大括号里面的属性
		
三, 属性选择器  $("li").parent()
		    .siblings("li")   除了自己以外的所有兄弟
            .parent()      查找最近的父级标签 
            .parents(li)    所有父级标签中叫li的
            .next()         下一个兄弟
            .prev()         上一个兄弟
            .preAll()        前面的所有
            .nextAll()       后面的所有
            .find("li")      某个标签里的所有某个标签
            .children()      某个标签里面的子元素
            .children(':last-child')     父级最后一个子标签
            .eq(index)       拿到下标元素( 多个兄弟才生效 )
            .index(1)        找下标  没有值就是获取到下标
            .children("ul")  父级里面的某些标签
            .append()        把某个内容放到哪去
            .prop("属性",true/false)   操作动态属性是否执行   只填属性,可以判断是否是执行的
            .html("")        把某个标签的内容都改掉    没参数为获取
            .text()          修改/获取/删除文本内容
            .empty()         清空盒子里面的内容
            .remove()        删除整个盒子
            .clone(true)     深克隆浅克隆    深拷贝会拷贝事件    浅拷贝会拷贝结构和样式 
            $(document).scrollTop    获取页面隐藏部分的高度
            .val()等于value()   获取文本内容
            .slice(0,3)       下标第0个到第三个,不包含3
            
            扩展: .end()链式属性里,返回到最初的元素
            	 .is(':checked') 判断某个按钮是否被选中

            
四, 动画的属性
		针对样式操作
            addClass("")  给元素添加css样式名
            hasClass("")  判断元素是否有该class类名
            removeClass("")  删除某个元素的class类名  没参数全删除
            toggleClass("")  样式切换,样式有和无之间切换
            attr("属性","值")  给一个标签设置属性和值
            removeAttr("属性") 移除标签属性的值
            
            
        动画的样式 (两个参数时,第二个为回调函数)
            正常左上角显示隐藏
            show()        //显示
            hide()        //隐藏

            下拉式的方法
            slideDown()        //下拉式隐藏
            slideUp()          //下拉式展开
            slideToggle()      //两个之间切换

            淡入淡出的方法 
            fadeIn()           //显示
            fadeOut()          //隐藏
            fadeToggle         //切换
            fadeTo(1000,0.5)   //改变透明度,增加一个透明度选项

            自定义动画(第一个为内容,第二个时间,第三个回调函数)
            animate({},1000)    //正常移动动画    有四个时,第二个为动画匀速
            stop()             //每次停一次动画
                里面有true false 两个值  
                    第一个为是否清空后续队列动画
                    第二个为是否快速完成该次动画
                    
五, 创建一个标签元素
		    $("<div>标签</div>")      //直接就创建了一个div
            $("body").append()       //把内容加到某个标签结尾  前父后子
            $("box").appendTo($("body"))  //最后添加一个标签   前子后父
            $("box").prependTo("body")    //放到第一个个     前子后父
            $("body").prepend()      //把内容加到某个标签开头     前父后子 
            $("li").before($div)     //插入到什么标签的前面   
            $("li").after($div)      //插入到什么标签的后面
            $("li").text(123)       //把标签里面的内容改掉,跟innertext一样

六, 表单操作
		:checked    寻找表单按钮被选中的
		.val()等于value()     获取表单元素里面的内容
		.position()           获取定位元素的位置   只能获取
		.offset({属性:值})     设置元素到body的位置            加.left可以获取
		
1. jq事件
一, jq的委托绑定事件
		对象.bind("事件",函数)                   给对象绑定什么事件执行什么内容
		父级对象.delegate("对象","事件",函数)     父级下面的哪个对象绑定事件
		对象.on("事件",函数)                      给对象绑定什么事件执行什么内容
		父级.on("事件","对象",函数)                给对象绑定什么事件执行什么内容
		
二, jq解绑事件
		$("body").off()      解绑所有跟body有关的事件   
             off("事件","对象")   解绑指定事件或者指定的对象
             off("事件","**")    除自己之外的所有对象解绑
             
三, 其他事件
		resize   改变页面窗口大小事件
        preAll   获取一个标签前面的所有标签
        nextAll  获取一个标签后面的所有标签
        $(evt.currentTarget)   点击目标为当前的元素
        
        遍历事件 结束return false;   true是结束当前,继续下一次循环
        each((下标,值)=>{})       遍历一个内容
        each(对象,(下标,值)=>{})   可以遍历非jq数组
        map(对象,(下标,值)=>{})    可以遍历非jq数组,有返回值

2…jq动态版本和插件
一, jq使用版本的切换    .noConflict()
		当导入两个jq版本时,优先使用后面的,通过该功能,可以让一个符号使用前面的版本
			例子: $.noConFlict()   可以更改$的控制权指向
			
二, jq插件的导入
		注意:需要导入在jq正常版本的后面,
	

十五, Git的操作

, git的使用
		pwd        /查看当前路径
        ls         /查看当前坏境应用所有路径
		mkdir 名字 /创建一个文件夹 
        cd         /进入某一个路径
        cd ../     /返回上一级
        rm -rf     /删除和强制删除文件或者文件夹
        clear      /清屏
        touch .gitignore  /创建过滤文件
        touch index.html /创建一个文件
        vi index.html    /打开一个文件
        		i 进入编辑状态    esc结束编辑       shift+: + wq 保存并退出
        		
二, 其他使用
		配置文件
			git init      创建一个空的暂存区,也就是隐藏的git文件夹
			git status    查看文件状态,如果是红色,就需要关联,或者过滤
			git add .     把当前目录里的文件和暂存区关联
			git commit -m '这次操作的注释'
			git config --global user.email   文件的邮箱,一台电脑只需要设置一次
			git config --global user.name    文件的名字,一台电脑只需要设置一次
			
			git config --list   查看配置文件
			git config --global --edit   编辑配置文件
			git reflog      查看历史编辑记录
			git reset --hard 编号   回到某次历史,进行编辑
			
		分支操作
			git branch     查看分支
            git checkout -b 分支名    新建一个分支
			git branch -d 分支名    删除一个分支
			git checkout '分支名'   切换到一个分支
			git merge 分支名     合并子分支(文件在一起)
			
		码云和git绑定,需要码云秘钥
			git remote add 名字 码云的SSH进行提交 ( 需要在码云创建一个仓库 )
			git push --force origin master   提交失败就强行提交
			git remote remove 名字  删除名字
			
		同步到码云
			git push -u --force 名字 master   第一次提交到码云
				第二次提交不需要 --force
				
		下载码云的文件
			git clone SSH地址
			
1. less和sass
, less的安装使用( 注意:一个台电脑只需要安装一次 )1:   安装 cnpm 淘宝代理的npm镜像包 ( 选择第一行,等待安装 )2:   cnpm -v  版本号  查看是否安装成功
		第3:   cnpm install -g less
		第4:   lessc -v   查看是否安装完毕
		第5:   lessc  ./src/index.less   ./src/index.css ( 同步文件 ), sass的安装使用
		第1:   gem sources ‐‐remove https://rubygems.org/  删除现有的,没有需要安装
		第2:   ruby -v    查看安装的版本号
		第3:   gem sources --add https://gems.ruby-china.com/ --remove
        		  https://rubygems.org/     添加源码/安装
		第4:   gem sources -l     打印是否替换成功,如果成功了   *** CURRENT SOURCES ***5:   sass ./sass/index.scss ./css/index.css    ( 同步文件 )
				同步方式: sass ‐‐style compressed ./test.sass ./test.css
					compressed  压缩后的代码
					compact     简洁的css代码
					expanded    没有缩进的css代码
					nested      默认值css代码
					
三, 安装gulp,一种流程化工具
		第1:   cnpm install gulp -g      全局安装
		第2:   gulp -v                   查看是否安装成功,版本号
		第3:   目录下面创建  gulpfile.js/压缩文件   .gitignore/用来排除文件( git创建 )4:   cnpm init -y               配置一个管理工具,把配置文件还原
		第5:   会自动生成 package.json 文件,里面会放置安装好的版本号
		第6:   cnpm i gulp@3 --save-dev      生成配置文件
		第7:.gitignore    添加node_modules
		第8:   gulp +名字    ( 安装好压缩的文件后,再运行 )9:   压缩文件的安装-引入: const gulp = require("gulp")10:  (html安装)百度搜索,npm,然后搜索gulp-htmlmin 
					找到并运行 cnpm install gulp-htmlmin --save-dev
					或者 cnpm i gulp-htmlmin -D11:  (sass安装)搜索gulp-sass  
					找到并运行 cnpm install node-sass gulp-sass --save-dev
		第12:  (css安装) cnpm i gulp-clean-css gulp-autoprefixer --save-dev
		第13:  创建css私有前缀,执行顺序需要再css压缩之前
		第14:  (js安装) cnpm i gulp‐uglify gulp‐babel@7 babel‐preset‐env@1 ‐‐save‐dev
		第15:  (兼容ES6) 创建一个 .babelrc文件(git创建)  里面填入 {
    
    "presets": ["env"] }16:  (安装babel) cnpm i babel‐core@6.26.3 --save-dev ( 主要是ES6ES5 )17:  (图片安装) cnpm i gulp‐imagemin ‐D
		
		提示:    如果发现报错,优先查看插件是否安装成功 ( package.json )      
			     还有错误,查看关键词是否写错或者不匹配
			     
四, gulp的语法 ( 其他的八九不离十 )
		const sass = require('gulp-sass');    //引入主模块
		sass.compiler = require('node-sass');  //引入sass压缩模块
		gulp.task("sass", () => {
    
    
			gulp.src("./sass/*.scss")
				.pipe(sass({
    
    }).on('error', sass.logError))
				.pipe(gulp.dest("./src/css"))
		})
		
	CSS添加私有前缀
		const autoprefixer = require('gulp-autoprefixer');   //引入主模块
		gulp.task('testAutoFx', function () {
    
    
			gulp.src('src/css/*.css')
				.pipe(autoprefixer({
    
    
					browsers: ['last 2 versions', 'Android >= 4.0'],
					cascade: true,         //是否美化属性值 默认:true 像这样:
					remove: true           //是否去掉不必要的前缀 默认:true
				})).pipe(gulp.dest('dist/css/'));
			});
						

十六, NodeJS

, node基础知识
	name=require("模块名");     引入某个模块
			http /http模块                   url /url模块          
			querystring /qs模块              fs  /fs模块
			
	扩展:  安装插件( 可以实现自动刷新发布 )  cnpm i nodemon -g
        	nodemon 页面名字.js     //可运行指定页面
, http模块
		var http=require("http");     引入http模块
		//创建一个服务器,有人访问了,就执行里面的内容
		var server=http.createServer((request,response)=>{
    
       //创建一个http响应服务
					//让浏览器以指定的格式和编码进行解析
				response.writeHead(200,{
    
    "Content-type":"text/html;charset=utf-8"})
				response.write("向浏览器发送的内容");        //返回给浏览器的内容
				response.end();                           //响应完了 结束
			})
			
		server.listen(8081,()=>{
    
    })    //监听,设置一个端口对应一个服务内容  回调函数判断是否在运行
		扩展: request  :浏览器通过http向服务器发送的东西
        	 response  :服务器接收到发送过来的东西,返回给浏览器的内容
			 requset.url  浏览器向服务器请求的内容( get请求 )
        
        get请求: 传过来的数据直接显示在url上, requset.url可以直接拿到传输内容
	    post请求: 传过来的数据url看不到,通过两个事件可以查看
			事件1: resuest.on('data',(aa)=>{
    
     str+=aa })  //数据传输执行(n次)  aa为接收的数据
            		提示: 数据分多次传输,需要拼接起来
			事件2: resuest.on('end',()=>{
    
    })  //数据传输完毕后执行(1次), url模块
		var URL=require("url");     引入url模块
		
		//假设一个链接
		var url = "http://127.0.0.1:8080/api/login?uname=abc123&upwd=123#abc"
			URL.parse(url)         //解析一个url链接,把链接的每个部分进行拆散
			URL.parse(url).query   //提取解析后的某一个内容 ( uname=abc123&upwd=123 )
			URL.parse(url,true).query  //把某个内容解析后,转为对象
			
		扩展: 一个完整的链接分别为
				http:                  声明头/协议      protocol
				127.0.0.1.8080         主机/服务器      host主机名字( hostname ):端口( port )
				/api/login             路径            pathname
				?uname=abc&upwd=123    传输内容(带问号)  search
				uname=abc&upwd=123     传输内容         query
				#abc                                   hash
				
三, querystring模块
		var qs = require("querystring");   引入qs模块
		
		//假设一个query字符串
		var url = "uname=abc&upwd=123&sex=男&sex=女"
			qs.parse(url,true)   //把接收的query字符串转成一个对象
			qs.stringify()       //把一个对象转成query字符串
			qs.unescape()        //把转字符串造成的文字乱码转文字
			qs.escape()          //把文字转乱码, fs模块 (异步的回调函数 err 判断是否存在该文件,返回null)
		var fs = require("fs");   引入fs模块
		
		fs.readFile() // 读取文件
				异步语法: fs.readFile("index.js",'utf-8',(err,data)=>{
    
    })
                同步语法: fs.readFileSync("index.js") //异步读取会直接返回,不需要data
			扩展: 读取出来的文件内容是二进制数据,通过.toString()转换
            	 回调函数的data是读取到的内容,不过是二进制数据
                    
       	fs.writeFile()  //在一个文件里写入内容,只会写一次 (覆盖) (err没找到文件会自己创建)
       			异步语法: fs.writeFile("index.css","写入的内容",(err)={
    
     })  //写入了返回null
				同步语法: fs.writeFileSync("index.css","写入的内容")
       			追加写入语法: 在回调函数前面加 {
    
    encoding:"utf-8",flag:"a"}
        
		fs.stat()   //检测是文件还是目录
                 语法: fs.stat("./node",(err,state)={
    
           
							if(err){
    
     没有该文件 }      //有该文件返回null  否则就是true
							state.isDirectory()      //这是目录   是为true  否则为false
							state.isFile()           //这是目录   是为true  否则为false
                      })
                      
        fs.mkdir()  //创建一个文件夹 ( 有同步和异步 )
        		异步语法: fs.mkdir("css",(err)=>{
    
    
						    if(err){
    
     创建失败 }    	  //有该文件返回null  否则就是true
        				})
        		同步语法: fs.mkdirSync("css")         //如果没有该文件返回undefined
       			
        fs.appendFile()  //在一个文件里追加写入内容
        		语法: fs.appendFile("index.css","写入的内容",{
    
    encoding:"utf-8"},(err)=>{
    
    })
        	
        fs.rename() //重命名文件的名字
        		语法: fs.rename("js","jsA",(err)=>{
    
    })    //现有的文件名和改后的文件名
		
		fs.unlink() //删除一个文件
				语法: fs.unlink("js",(err)=>{
    
    })
		
1.express框架
express项目生成器
	//创建跟目录文件夹
	//文件夹初始 npm init   然后安装express包
	//安装: npm install express-generator -g
	//创建项目 express 名字  然后安装依赖包和运行项目, 安装express框架 
        第一步:  npm init -y     //初始化一个环境
        第二步:  在项目目录下安装   cnpm i express --save-dev

二, 开始使用( 先引入 )
        var express = require("express");   //引入express模块  
        var server = express();       //类似前面的http,建立一个服务器
			server.listen(8080)       //监听服务器端口
		var expressStatic=require("express-static")  //引入读取文件模块
        		server.use(expressStatic('读取的文件'))  //让服务器读取哪个文件
					提示: 这样url访问的时候,会直接在读取的文件里面寻找

	//响应用户的请求后做什么( get请求和post请求都可以 )
	server.all('/index.html',(request,reponse)=>{
    
    
        reponse.send("向浏览器发送的内容");        //返回给浏览器的内容
        reponse.end()                           //服务器响应完了,结束
    })

    //get请求或者post请求 后做什么   all为两个请求都支持   use使用某个中间件
    server.get("/index.html",(request, response, next)=>{
    
    
        request.query()                         //拿到用户名和密码 ( 对象格式 )
    })
    request   发送给服务器的url(含每个部分)  request.query 拿到get请求的用户名和密码
    response  服务器返回给浏览器, 该模式下   response.json() 可直接把对象转字符串
    next      执行某个服务内容后,继续往下走   next()    //该服务执行完毕,去下一个服务
	params    能单独拿到query前面的id部分   reuest.params.id  也是访问端口后面的:id
  
2. express框架-中间件
, 安装插件
		第一步: npm init -y
		第二步: cnpm i express --save-dev     //安装express框架
		第三步: cnpm i body-parser --save-dev
		第四步: cnpm install cookie-parser --save-dev    //安装cookie中间件, 引入模块( 多个 )
		var bodyParser=require("body-parser");, 配置中间件
		server.use(bodyParser.urlencoded({
    
      //use为使用该配置
    		limit:"500mb",   				//设置传输的数据大小
    		extended:false   				//是否使用扩展
		}));
		//通过use启用中间件的一些插件
		server.use(bodyParser.json());		 //让浏览器发送的json也支持, cookie中间件的配置
		1. server.use(cookieParser("JM"))    //配置的时候加密,防止被修改,不加密去掉 "JM"
		2. res.cookie("avc123","123456")     //服务器向浏览器发送的内容
					加密方式: 后面加{
    
    signed:true}  启用加密
        3. req.signedCookies      //服务器接收浏览器带来的cookie  加密的方式
		4. req.cookies            //服务器接收浏览器带来的cookie  未加密的方式
		
3. 自定义中间件/模块
, 本地创建
		require  外部引入模块   require("./md")  //需要加./ 除非是放在模块文件夹里面
		exports  输出一个变量   exports.str   //输出str这个变量,外部可以引用
		module   批量输出变量   module.exports={
    
     内容或者执行函数 }
				 调用: const db = require("./libs/DbHlper") //默认加载index.js
		语法: module.exports={
    
       //往外暴露一个对象,这样外部可以直接通过路径引用
            	url(){
    
               //闭包函数
                    return function(req,res,next){
    
    
                        req.on("data",(data)=>{
    
    })        //post请求多次获取传输内容
                        req.on("end",()=>{
    
     next() })    //获取完,返回出去,然后继续往下走
                    }
                }
        	}, 模块提交
		初始化模块信息 npm init   //然后填写模块名字,版本,描述,主文件地址,
4. cookie
, 下载引入( npm网站搜索 )
		cnpm install cookie-parser --save-dev        //下载
		var cookieParser = require("cookie-parser")  //引入, cookie的一些设置
        server.use(cookieParser("JM"))    //配置的时候加密,防止被修改,不加密去掉 "JM"
	
		res.cookie("avc123","123456");    //服务器向浏览器发送的时候添加,在服务里面(不启用加密)
				加密写法:  {
    
    signed:true}  传输内容后面再增加一个对象( 有多个信息 )
					maxAge:1000毫秒     path:./www    //指定目录下访问该网页才能读取
                
        req.signedCookies    //读取所有带签名加密的cookie内容
		req.cookies          //读取所有不带签名的cookie内容
		res.redirect("/login");  //页面地址的跳转


5. session
, 下载引入( npm网站搜索 )
		cnpm install cookie-session --save-dev        //下载
		var cookieSession = require("cookie-session")  //引入, session的一些设置
		server.use(cookieSession({
    
    
    		name: "1000phone",              //设置秘钥
    		keys: ["aaa", "bbb", "ccc"],    //三个秘钥随机使用,更安全
    		maxAge: 1000 * 60 * 20          //如果超过20分钟,不发送请求到服务器,cookie也消失
		}));

		req.session["currentUser"];  //获取或存储session里面的内容,跟cookie差不多
				值是一个对象{
    
     uname: 'abc123', upwd: '123456' }



十七, 数据库

-- 数据库的脚本 后缀是 .sql

-- 插入语句
-- insert into 表名称 (字段,...)values('值',...)
INSERT INTO userinfo (u_name,u_pwd,u_sex)VALUES('abc123','123','男')

-- 查询语句( 查询一个表 )
-- 语法 select * from 表名称
SELECT*FROM userinfo

-- 查询的登陆  ( and==&& )  查询断数据  前面设置展现哪些内容
SELECT `u_id`,`u_name`,`u_sex` FROM userinfo WHERE u_name='abc123' AND u_pwd='123'

-- 修改  where 用于接调剂  根据id修改某个信息
UPDATE `userinfo` SET u_sex='女' WHERE u_id=1

-- 删除  根据id删除一段数据
DELETE FROM `userinfo` WHERE u_id=1

-- 软删除,不是物理删除,拒绝物理删除
SELECT*FROM userinfo WHERE u_status=1

-- 所谓的软删除就是把状态改成0
UPDATE userinfo SET u_status=1 WHERE u_id=1
1. sql数据库连接
,SQL数据库的连接
		cnpm i mysql --save-dev    //引入sql模块,才能连接到数据库

		var conn = mysql.createConnection({
    
            //1.创建数据库连接
            host: 'localhost',      //SQL主机
            user: 'root',           //用户名
            password: '',           //密码
            database: 'cs1905',      //数据库名字
            port: 3306           //端口号
        })
        conn.connect();         //2.连接数据库  里面有回调函数错误先行
        
        //登陆接口
        
		//3.准备sql语句( 也就是前面sql的一些命令 )
		var sql = "SELECT * FROM userinfo WHERE u_name=? AND u_pwd=? AND u_status='1';"
        //4.执行sql语句
        conn.query(sql, [req.query.uname,req.query.upwd], (err, result, fields) =>{
    
    
            //准备的sql语句 - 参数(传输过来的内容) - 回调函数(错误,结果,字段)
            if (result.length >= 1) {
    
          //5.拿到sql结果,判断结果,大于等于1,就表示拿到数据了
                //result 是在数据库查询到的返回结果
                res.json({
    
                 //返回一些状态
                    msg: '登陆成功',
                    status: 1,
                    data: {
    
     u_id, u_name, u_sex }           //把登陆成功的账号,性别返回出去
                })
            }
        }
                   
        //注册接口
        
       	//3. 准备sql语句( 也就是前面sql的一些命令 )
        var sql = "INSERT INTO userinfo (u_name,u_pwd,u_sex)VALUES(?,?,?)"
        //4. 执行sql语句
        conn.query(sql, [req.query.uname, req.query.upwd], (err, result, fields) =>{
    
    
            if (err) {
    
                      //判断,如果跟数据库相同,就报错
                res.json({
    
    
                    msg: '执行异常',
                    status: -3,
                    err: err.message    //返回错误的详细信息( 用户名什么的已存在 )
                })
                return;
            }
            conn.destroy(); //释放连接  创建一次数据库连接就释放掉
            if (result.affectedRows >= 1) {
    
         //判断受影响行数是否为1 
                res.json({
    
    
                    msg: '注册成功',
                    status: 2
                })
            }
        }
2. 图片的传输
, 模块的引入   安装: cnpm install multer --save-dev
		const path = require("path");   //获取文件的扩展名模块
        const multer = require("multer");  //引入图片上传功能模块, 配置模块
		//设置图片的目标路径	( 会自动在根目录生成文件 ) 也是上传访问的路径
        const upload = multer({
    
              //设置图片的目标路径
            dest: "./public"
        })
        app.use(upload.any())  //全部的上传路径都可以传任何文件

        //配置静态服务器 中间件
        app.use(express.static("./public/"))   //可以随意访问该文件夹的内容
		
		//解决跨域问题
        app.use("*", (req, res, next) => {
    
    
            req.header("Access-Control-Allow-Origin", "*")
            next()
        })
		
        //设置图片上传,  使用req.files拿到图片的一些信息
		// upload.any() 只给这个路径配置的方法,可以上传任何文件
        app.post("/upload",upload.any(),(req,res,next)=>{
    
    
            // 如果req.files.length为0 就是上传失败
            //获取到图片的传输地址+文件扩展名
            //path得到文件路径和名字     path.extname模块方法获取到文件的扩展名
            var newPath=req.files[0].path+path.extname(req.files[0].originalname)
            //用fs模块来重命名文件 
            fs.rename(req.files[0].path,newPath,(err)=>{
    
    
                //err报错就是有找到文件名  否则就是上传成功
            }
        }, JQ实现图片的预览功能
        $("#file").on("change", function () {
    
          //上传文件标签内容进行改变时执行
            var fr = new FileReader();             //读取上传的文件的数据
            fr.readAsDataURL(this.files[0])        //将文件以数据URI的形式保存在result属性中
            fr.onload = function (e) {
    
                 //文件数据读取完成后触发事件
                var ele = e.target || e.srcElement;
                $("#img").attr("src",ele.result)     //ele.result是图片的本体  并设置到IMG
            }
        })
3. 路由
, 路由的介绍
		路由就是一个管理工具,,用来管理某个路径
        
二, 路由的设置
		1. 先引入express模块  且创建服务
        		import express from "express"   //一种新的引入方式 需要babel才能识别
		1.1 安装babel-cli来识别新的语法 
        		cnpm install babel-cli babel-preset-env --save-dev
				安装预设
                	cnpm i babel-plugin-transform-runtime --save-dev
					cnpm i babel-runtime --save-dev
		1.2 创建 .babelrc文件,里面填入
					{
    
    "presets": ["env"],"plugins": ["transform-runtime"]}
		1.3 修改 package.json 配置文件里面的 scripts   然后执行 npm start
        			"test": "echo \"Error: no test specified\" && exit 1",
                    "start": "nodemon --exec babel-node app.js"  //app为文件名
        2. 创建一个路由   
        		const userRoute=express.Router({
    
       //可添加审核要求,也可以不添加
                    caseSensitive:false,           //区分大小写
                    strict:true                   //严格模式
                });
		3. 用来解析文字乱码
        	app.use("*",(request,response,next)=>{
    
    
                response.header("Content-Type","text/html;charset=utf-8")    
                next()
			})
		4. 给路由管理的路径( 以及里面的子路径 )
        	app.use("/users",userRoute);      //userRoute与创建路由名字对应
		5. 让路由管理的子路径
        	userRoute.get("/add/:id",(request,response,next)=>{
    
    
                console.log(request.params.id)  //params跟query差不多, params可以获取纯数字   
                response.end("恭喜")
            })

猜你喜欢

转载自blog.csdn.net/weixin_43689726/article/details/126222709