html5 css3 JavaScript 语法

1.html5
1.环境搭建

	1)编辑器环境
 			轻量级的编辑
 			sublime(装emmet插件)
 			vscode(在用)
 	2)浏览器环境(测试)
 			firefox
 			google chrome
			opera
			safari(mac)
			ie8+(兼容性)

2.编写简单的hello world

编写代码  -> 运行测试 -> 交付(部署到服务器)【网站】
	1)部署在tomcat中  (动态服务器 - 慢)
	 	主要是放在tomcat的webapps目录下
	 	tomcat/webapps/hello.html
	2) 部署到静态服务器(apache/nginx)
		阿里云(Ubuntu16.04)139.196.164.93    *我自己的网站*
		在服务器上安装jdk mysql apache tomcat
	(* 本文最后会有阿里云服务器搭建的相关简易步骤,上传文件,安装mysql等)

3.html结构(超文本标记语言)

	1.超级文本(文本,超级链接,图片,视频,音频等)
	2.doctype说明:
		HTML5:
		HTML4:  "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www/w3.org/TR/html4/loose.dtd">
	3.html的主体结构
		
		"en">
		
			
		    "UTF-8">
		    "viewport" content="width=device-width, initial-scale=1.0">
		    Document
		
		
		    	
		
		
	4.与xml的简单对比
		xml:标签是可以自定义的。
		html:所有标签都是内置的。
				

一级标题

5.语法 html有各种元素组成,一个元素通常包含开始标签,结束标签,内容 。在开始标签中可以添加属性。
"content" id="one"> hello world
属性: 1)核心属性:id,class,title,style 绝大多数元素都具备的属性 2)特有属性 某些元素中特有的属性 ex: a href target img src width height

4.对于html与java的一些简单的描述

	1.java  编译型语言  .java->.class->jvm
			隶属于sun/oracle公司的,有具体的团队维护,所有的标准oracle说了算,jvm也是oracle开发的
			关于java语法的升级,有版本的区别
			jvm升级(解释java代码)效果升级
			springboot写完代码之后是如何部署
				1)打包成war,直接抛到tomcat/webapps,war就会自动解压
				2)打包成jar,直接运行jar就行(内置了tomcat)
	2.html  解释型语言 .html->浏览器
				1)网页编程标准  w3cschool
				2)h4-->h5
					语法升级,版本相差不会很大
					就会废弃一些属性
					新增一些属性
					就是进行一些优化,效果升级

5.标签 【对于以下内容的学习,编写的代码已上传到github仓库中】通过以下网址可以进行访问(public):https://github.com/Jackson0036/Front-end-

	1)块级标签(常用的)
		作用:用来搭建网页的结构
		特点:宽度默认占满父元素,高度默认有内容决定,宽高可以自定义,独占一行
		div 				【容器】无意义的块级元素
		h1~h6			【标题】
		p					【段落】
		ul>li				【容器】列表
		ol>li				【容器】列表
		dl>dd,dt		【容器】列表
	2)行级别标签
		作用:填充网页
		特点:默认宽高都由内容决定,宽高无法指定,所有的行内元素可以共享一行空间,行内元素内部一般不允许嵌套子元素,只允许放文本
		span 		【】无意义的行内元素
		a				【超链接】
		img			【图片】
						  src  图片地址
						  alt   当图片找不到的时候的文本替代 
		strong,b	 加粗
		em			 强调
		i 				斜体

2.css入门:

1.三要素:

	1)html (网页的骨架)
	2)css(进行页面修饰,布局,动画过渡效果)
			原则:对于动画效果能用css实现的绝对不用js
	3)JavaScript(树莓派)
			动态DOM,类似于jstl
			数据交互

2.如何在html中使用css(3种方式)

	1)嵌入在标签的内部
	 		将css代码写在html中,较为混乱,复用性低, 好处:优先级高,简单直接(修改别人代码的时候  weex rn)
	2)集中嵌入在style标签中(我在学习过程中使用的比较多)
	3)将css独立写在外部的css文件中,并且通过link导入进来(适用于企业级的开发)

3.css语法

选择器{
	/*规则*/	
	color:#fff;
	background-color:pink;
 }
css选择器(jQuery选择器)
1)核心选择器
 		用法:选择较大范围
 		1.标签(元素)选择器
 			div{}
 			h1{}
 		2.id选择器
 			#one{}
 			
one
3.class选择器 .first
{}
one
4.并且选择器 div .first
{} div #one{} 5.或者选择器 div,.first{} 6.普遍选择器 *{} 2)层次选择器 1.子代选择器 .top_nav > ul >li 选中class为top_nav的元素的直接后代ul元素的直接后代li元素 2.后代选择器 .top_nav li 3.下一个兄弟选择器 .top_nav li + * 4.之后所有的兄弟选择器 .top_nav li ~ * 3)过滤器 对已经选择到的元素进行过滤 1.属性过滤器 selector[name] 已选择到的元素具有name属性 selector[name=v] 已选择到的元素具有name属性,并且name属性的值为v selector[name^=v] 已选择到的元素具有name属性,并且name属性的值以'v'开头 selector[name$=v] 已选择到的元素具有name属性,并且name属性的值以'v'结尾 selector[name*=v] 已选择到的元素具有name属性,并且name属性的值中包含了'v' 2.伪类过滤器 以:开头的 selector:first-child 过滤出已选择元素中的是第一个孩子的元素 selector:last-child 最后一个孩子 selector:nth-child(2) 第二个孩子 selector:nth-child(odd) 奇数孩子 selector:nth-child(even) 偶数孩子 selector:nth-child(3n+1) n为0开始 selector:only-child 如果某个元素是其父元素的唯一子元素,那么它就会被选中 selector:not(selector) 没有被选择的元素 3.伪元素过滤器 可以产生一个虚拟元素(行内元素)可以用来加一些特殊的符号 ^ - - 等 以::开头的 div::after{} div::before{}
::before

one

::after

4.css规则 以下都可以参考【mdn】进行学习 mdn

	单位值 px 像素
		1rem=38px
		1em=12px
	  1)字体   【设计师-架构师规定】【可以被继承】
		font-size          字体大小      默认16px
		font-weight 		字体粗细程度
								normal 【默认】    
								bold		【加粗】
								bolder  【比当前元素上继承的值要大一些】
								100~900 
		font-style        风格(是否打开斜体)
								normal  【默认】
								italic
		font-family		字体族   "微软雅黑"
		line-height		行高
								绝对单位 1px
		速写
		font:[font-weight] [font-style] font-size/line-height font-family
	 2)网络字体(字体图标库)
	 	iconfont【阿里巴巴的字体图标库】
	 				【https://www.iconfont.cn/】
	 	1.选取自己想要的图标
	 	2.生成项目
	 	3.按照说明进行使用
	 3)文本 【可以被继承】
	       text-align
	       		left    居左排列
	       		center 中
	       		right    右
	       text-indent  文本缩进
	       text-decoration
	       		line-through  划掉文本的线
	       		overline      	 文本上边的线
	       		undeline       下划线
	       		none			无
	             text-tranform        字体大小写转换
	                      uppercase
	                      lowercase
     4)列表
     				list-style:none
     5)盒子
     			 margin
     			 padding
     			 border
     			 width
     			 height
     6)背景
     			background-color      背景色
     						关键字  		teal    red   black
     						十六进制		#ffffff  #000000
     						rgb函数		rgb(255,255,255)
     						rgba函数		rgba(0,0,0,.5)多了一个透明度
     		    background-clip    背景覆盖区域
     		    			border-box    边框及边框以内全部覆盖
     		    			padding-box  内边距及内边距以内全部覆盖
     		    			content-box 内容区域全部覆盖
     		    background-origin : border-box;
     		    					背景铺设的起点
     		    background-image :url("./images/a.jpg");
     		    					背景图
     		    background-repeat: no-repeat;
     		    					背景图的重复方式
     		    background-size:contain;
     		    					背景图片的大小
     		    background-position:50px 50px;
     		    					关键字 center
     		    					坐标点 1px 2px
     		    					背景图开始铺设的坐标
     		   速写:background:

5.css布局
布局就是为了解决多个块元素在一行中显示的问题。

1)默认文档流
	块元素从上到下进行排列	
2)浮动布局
	float:left;		向左侧浮动
	clear:left;		当前元素左侧不允许有浮动元素,换行
	display:block;	将一个元素设置为块元素
		"display:block">
 	应该加在块元素上。
 	1.特点:
 		1)宽高默认由内容决定
 		2)脱离文档流,在默认文档流中不会再占据空间
 		3)在同一层次中,所有的浮动元素会在一行显示,当一行中无法容纳这些浮动元素的时候,就会自动换行
 		4)浮动元素会失去对父元素的支撑
 	2.解决浮动元素的父元素没有高度问题
 		1)所有子元素浮动,通过伪元素进行支撑
 		2)保留一个子元素不浮动,用于支撑父元素,为了让他显示出来,可以加margin
3)定位布局
	position:static;【静态】
	position:relative;
	position:absolute;
	position:fixed;
	position:sticky;
	如果一个元素具有position规则热,并且规则为relative,absolute,fixed,sticky之一,那么,我就认为这个元素是一个定位元素;只有定位元素才能使用如下规则:
	left,right,top,bottom
	
	1.相对定位
		position:relative;
	 	特点:
	 		1)相对于当前元素所在位置
	 		2)当前元素不会脱离文档流(即使发生了移动也不会被其他元素抢占位置)
	 	应用:
	 		一般情况下相对定位要配合绝对定位来进行移动
	 2.绝对定位
	 	position:absolute;
	 	特点:
	 		1)相对于距离他最近的父定位元素,如果他的父元素没有定位元素,那就相对于浏览器视口
	 		2)脱离文档流(不占据默认文档流的空间,块元素的宽度不再为100%)
	3.固定定位
		position:fixed;
		特点:
			1)相对于浏览器视口
			2)脱离文档流(不占据默认文档流空间,块元素的宽度不再为100%)
			3)不会随着屏幕的移动而移动
	4.粘滞定位
 		
 问题:块元素居中?
 答:给块元素一个宽度 margin: 0 auto;
 

6.选择器的优先级

Important           特权
	!important
Specificity			权重(积分机制)
	1000			style属性中
	100				id选择器
	10				类选择器,伪类过滤器,属性过滤器
	1				元素选择器,伪元素选择器
Source  order		顺序

7.伸缩盒布局(响应式布局)

响应式布局(bootstrap[封装了一些布局代码,完成响应式布局],栅格系统)[bootstrap](https://getbootstrap.com)
"row">
"col-sm-2">1
"col-sm-2">2
"col-sm-2">3
"col-sm-2">4
"col-sm-2">5
"col-sm-2">6
1.语法
"parent">
1
2
3
【声明在父元素上的规则】 display:flex; 这个规则应用到父元素上,表示当前元素为伸缩盒。默认情况下,主轴在x轴上,交叉轴在y轴上 flex-direction:row/column; 默认情况下,为row(主轴在x轴上) flex-wrap:no-wrap/wrap; 默认情况下,为no-wrap,表示当容器中的子元素宽度超过了容器宽,不换行 justify-content:flex-start/flex-end/center/space-around/space-between; 对主轴上剩余空间的排列设置(不要使用flex-grow对剩余空间进行分配了) align-items:flex-start/flex-end/center; 交叉轴上的显示:交叉轴的开始排列/结束排列/中间排列 【声明在子元素的规则】 flex-basis:指定子元素的宽度基准【固定,相对】,width flex-grow:1; 对容器剩余空间的分配,1表示当前元素占据剩余空间的一份 flex-shrink:1; 对于亏损空间的垫付,1表示栈亏损空间的一份 快写:flex:flex-grow flex-shrink flex-basis; 2.封装 爬虫

8.表格与表单(html)
【一般应用在后台管理系统中】

1.表单
	与列表类似,用于展示一些数据,一般不用于布局,因为他的默认样式太复杂
	table    	表格容器
	caption 	表格标题
	thead		表格的表头
				tr > th > *
	tbody		表格的主题
				tr > td > *
	tfoot		表格的底部
				tr > td > *
				
	表格美化
	1.属性
		align:center;
		colspan 	跨列 【通过excel来操作模拟】
		rowspan		跨行
	2.css  首选方案!!
		table{
			border-collapse:collapse;
			width:90%;
			margin:0 auto;
		}
		table td,
		table th{
			border:1px solid #ccc;
			text-align:center;
		}
2.iframe
	将外部的一个网页链接进来你当前的网页中
3.表单
	注意:
		1.在企业级开发的时候,一般不直接使用这些表单,因为表单元素在不同的浏览器中显示的样子是不同的。一般使用组件(bootstrap,element-ui...)
		2.看点咨询精选
			发布文章功能			input type=""text
			文章所属分类			select 如果是二级分类,需要插件,树形下拉菜单
			正文			富文本编辑器(需要插件)
		3.在表单学习的时候
			掌握表单和表单元素的属性和特性
			掌握交互原理
	获取用户输入的数据,是用户与我们程序之间的一个数据桥梁
	同步:form表单的直接提交就是同步操作
	异步:form表单通过ajax提交
	
	form
		action  url(相对路径/绝对路径)
		method get/post
		ectype 【只有在method=post考虑,如果是get方式,参数将会被直接编码为查询字符串,无法更改】
			application/x-www-form-urlencoded
				默认值
				查询字符串
				name=jack&password=abc123*
				规则: 属性名与属性值之间通过=分割
					  键值对之间通过&分割
					  属性值中如果有特殊字符,会将这个给特殊字符转换为百分比格式【这也是为什么二进制不能使用这种编码】
					   ex:/ => %2F
			multipart/form-data		附件上传【二进制图片】
				如果表单中出现了二进制文件,"file" name="file"/>,就无法使用字符串查询,只能用这种协议
			text/plain
			application/json  【目前在同步请求中不支持,但是在ajax中是支持的】
			
	表单及元素
	
"text"/> 单行文本框 "password"/> 单行密码框 "file"/> 文件选择按钮,enctype必须为multipart/form-data "radio"/> 单选按钮 单选按钮一般会同时出现多个,这多个按钮的name值必须相等才能达到互斥的要求 value必须通过,这样当勾选某个单选按钮的时候会提交改按钮上的value值 "checkbox"/> 复选按钮 "reset"/> 将表单内容恢复默认 "submit"/> 提交按钮 "button"/> 普通按钮 ...【h5新增】 "search" placeholder="请输入关键字"/> 搜索框 "date"/> 日期框 多行文本框
鄙视链(了解) ex:嵌入式 -> java -> 前端 -> 美工 研究协议,自定义协议 -> 使用协议(http,请求头)-> 前端(知道有http)-> 美工(不知道)

9.动画

语法
	animation
		1)关键帧定义
			随着时间移动的一些列的css规则
			@keyframes name{
				0%{
					width:100px
				}
				50%{
					width:300px
				}
				100%{
					width:150px
				}
			}
		2)动画定义
			.move{
				animation-name:move;		指定关键帧名称
				animation-duration:2000ms;		设置动画持续时间(from-to)
				animation-timing-function:linear;		时间曲线
				animation-fill-mode:backwards;		动画完成后保持的规则(from/to)		
				animation-delay:1000ms;		持续时间
				animation-iteration-count:infinite;		重复次数
				animation-direction:alternate-reverse;		动画运行的方向
				animation:			以上的速写形式
			}
		3)应用
			
"move">
开源组件库 自定义组件库 flash(直播流-监控) 海康 flash 4)animation.css(css3 animation动画轮子) 1.导入animation.css 2.调用class 框架

10.过渡效果

一般表示在元素状态切换的时候的过渡效果
	transition-property
			规则名
			规则名1,规则名2[,...]
			all
			指明在状态切换的时候,哪些属性添加过渡效果
	transition-duration
			持续时间 ms/s
	transition-timing-function
			linear/steps
	transition-delay
			延迟  ms/s
	transition
			transition-property transition-duration [transition-delay]

11.变形

	tranform
		指定变形函数
	1)旋转
		rotate(deg)		旋转度数
		rotateX(deg)
		rotateY(deg)
		rotateZ(deg)
	2)平移
		translate(长度)
		translateX(长度)
		translateY(长度)
		translateZ(长度)
	3)放大
		scale()
		scaleX()
		scaleY()
	4)拉伸
		skew(deg)
		skewX()
		skewY()
	transform-origin
		指定变形的原点

12.媒体查询(响应式布局)

@media(媒体查询条件){
	选择器{
		规则
	}
}

1)媒体查询的应用设置
	1.直接应用在规则内部
		
	2.应用在link标签中
		
		
		
		
	3)应用在style标签中
	
	
	
2)注意:
	1.如果我们编写的网页运行在pc中,那么一般要给固定宽度,但是这个宽度如果随着屏幕的宽度发生改变,我们就称为响应式(.wrapper)
	2.如果我们编写的网页运行在大屏上,一般就采用满屏铺,不用指定wrapper
	3.如果我们编写的网页运行在mobile中,一般就采用满屏铺,不用指定wrapper,但是需要响应式布局

13.at规则(@)

1) @font-face
2) @keyframes
3) @media
4) @import
	   @import url
	   @import url list-of-media-queries;
5) @charset
	   指定当前css文件的编码格式(说明当前文件是使用xxx编码)
	   

14.css脚本语言(css预处理语言)【了解】

	sass
	less

15.bootstrap4(思路,封装) 【了解】

	第三方库:iconfont/animation.css/bootstrap
	bs 是css3的一个库,也就说我们如果用了这个库,就可以很少的去写css代码,因为css中提供了大量的选择及规则。我们只管通过类调用即可

	css库
	js库
	组件库

	bootstrap-reboot.css 		重置样式,类似于我们自己写的common.css,要比我们写的好多了
	bootstrap-grid.css 			栅格布局(封装了flex布局【bs4封装float布局】)
	bootstrap.css 				完整样式(包含重置样式,栅格布局,按钮,表格,下拉菜单,模态框...)


	vue (组件库-栅格系统、组件[table,form,button])
	

JavaScript

JavaScript
	优点:1.能对浏览器时间做出响应
		 2.表单验证,减轻服务器的压力
		 	前端对于登录所输入的账号密码做了限制
	
	学习方式:
		 1.推荐网站:
		 	代码练习:https://www.freecodecamp.one/
		 	mdn:https://developer.mozilla.org/zh-CN/
		 	csdn、博客园、掘金
		 2.推荐书籍:
		 	红宝书:JavaScript高级程序设计
		 	犀牛:JavaScript权威指南
	
	组成:
		1)ECMAScript5(es5) JavaScript语法标准
			变量,注释,操作符,流程控制语句,数组,函数,对象
		2DOM (文档对象模型)
			js操作html
			选中浏览器页面任意元素
				var dom = document.getElementById('#app');
			绑定事件
				dom.onclick = function(){}
			监听
				dom.addEventListener(function(){})
		3BOM (浏览器对象模型)
			js操作浏览器
				setTimeout(function(){})
				setInterval(function(){})
				alert()
	
	js解析器:
		1.目前所有的主流浏览器都有js解析器
		2.js不仅仅可以运行在浏览器中,还可以运行在服务器中
			js运行在浏览器中:动画,表单验证,ajax请求...
			js运行在服务器中:操作数据库,代码编译,网络...
			java可以通过sql语句操作mysql
			nodejs可以通过sql语句操作mysql
	
	nodejs下载(我是在root账户下,不是root账户下记得加sudo)
		1.更新源
			apt-get update/sudo apt-get update 只有更新之后,才能下载最新的安装包
		2.下载nodejs安装包
			apt-get install nodejs
			注意:如果下载完nodejs之后,没有建立软连接,就只能使用nodejs
			nodejs + 回车进入命令行模式
			node + 回车是无法进入的
		3.查看版本号
			nodejs -v
			出现版本号即说明nodejs下载完成
		4.创建软连接(快捷方式)
			ln -s /usr/bin/nodejs /usr/bin/node
			注意:如果报错'/usr/bin/node' file exits. 说明已经创建好了node的快捷方式
		5.退出node命令行
			.exit
			ctrl+cc
			
	创建hello.js
		1)使用vi hello.js创建文件
		2)编写代码
		3)执行代码
			node 文件名
			
	配置vi编辑器
		spf13(为了更好的写代码,自动补全,下载时间较长)
		1)下载git
			apt-get install git
		2)查看版本号
			git --version
		3)下载spf13
			curl https://j.mp/spf13-vim3 -L > spf13-vim.sh && sh spf13-vim.sh
		 	注意:下载spf13时,要预先安装好Git
	
	变量
		1) 强类型
			int a = 2;
			a是一个值为2的整数类型,类型是由int
			a = false;
			以上表达式会报错,因为a是一个整数类型,不能再赋值成其他数据类型
		
		2) 弱类型(变量的数据类型可以随时变换)
			var a = 2;
			a是一个值为2的数字类型,类型是由a = 2
			var b = 'hello'
			b是一个值为hellow的字符串类型,类型是由b = 'hello'
			a = false;
			将a的数据类型由数字类型转换为布尔类型
	
		3) 变量声明
			使用关键字var
			var a;
			var obj;
			var arr;
			只是声明一个变量,但是没有初始值,打印的时候值为undefined
	
		4) 变量初始化
			a = 2;
			obj = 'hello';
			arr = 123;
			变量声明和初始化同时进行
			var name = 'xpf';
			
		5) 变量的使用
			var a = 2;
			a++;
			注意:如果变量没有声明,会报错xxx is not defined
	
		6) 变量的数据类型
			基本数据类型
				数字类型		number
				字符串类型	string
				布尔类型		boolean
				null		
				undefined	
			引用数据类型
				对象
				函数
				数组
				正则表达式
				...
	操作符
		1) 算术运算符
			++=
				var a = 1;
				a += 1;	// 2
				等同于	a = a + 1--=
			**=
			/%	取余

		2) 一元运算符
			++	 自增
				a++;
					后置,先使用变量,再自增
				++a;
					前置,先自增,再使用变量
	
				var a = 2;
				var b = a++;
				console.log(a);	// 3
				console.log(b); // 2
	
				var a = 2;
				var b = ++a;
				console.log(a);	// 3
				console.log(b); // 3
			--	 自减
			+-	 将其他数据类型转换为数字类型
				var str = 'hello world';
				console.log(typeof(str));	//string
				console.log(typeof(+str));	//number
				console.log(typeof(-str));  //number
	
				1. typeof()可以用来检测基本数据类型,检测引用数据类型的时候,返回值并不精确
				2. isNaN()可以用来检测一个变量是否是一个数字,返回一个布尔类型的值
					NaN: not a number
					var str = 'hello world';
					isNaN(str);	//	true
					var a = 1;
					isNaN(a);	//	false
	
		3) 逻辑运算符(表单验证)
			&&	并且
				两个表达式中,只要有任意一个的返回值为false,它都返回false
				var a = true;
				var b = false;
				var c = a && b;
				console.log(c);	//fasle
	
				var age = 17;
				var gender = 'male';
				console.log(age > 18 && gender == 'male');	//	false
	
			||	或
				两个表达式中,只要由任意一个的返回值为true,它都返回true
				var a = true;
				var b = false;
				var c = a || b;
				console.log(c);	//	true		
	
			!	非
				取反
				var a = true;
				var b = !a;	
				console.log(b);	// false
	
				!true // false
				!false // true
	
		4) 比较运算符
			==
			!=
				双等,比较值,会自动转换数据类型
				var a = 1;
				var b = '1';
				console.log(typeof(a),'a');	// number
				console.log(typeof(b),'b');	// string
				console.log( a == b );		// true
				console.log( a != b );		// false
				console.log( a === b );		// false
				console.log( a !== b );		// true
			===
			!==
				三等(全等),比较数据类型和值,先比较数据类型,如果数据类型不一致,就算值是一样的,仍然返回false;只有当数据类型一致的时候,才去比较值
			>
			>=
			<
			<=
	
			var age = 17;
			console.log(age > 17); // false
			console.log(age >= 17); // true
			
		5) 三目运算符
			exp1 ? exp2 : exp3
			先判断exp1,exp1为true的时候,返回exp2;exp1为false的时候,返回exp3
			var age = 18;
			var gender = 'male';
	
			//酒吧:年龄在18岁及以上的男性才能入场
			var result = age >=18 && gender == 'male' ? '可以入场' : '不允许进入'
			console.log(result);
	
		6) 拼接运算符
			+
			当使用'+',操作数中出现了字符串,那么肯定就是拼接运算符
			var name = 'xpf';
			var age = 25;
	
			function sayName(name,age){
			    console.log('my name is' + name + 'my age is' + age);
			}
			sayName(name,age);
	
			1、案例一:
				根据父栏目id查询子栏目
	
				娱乐		
					八卦、媒体、周边新闻...
				新闻		
					军事、篮球...
				体育	
	
			2、案例二:
				情况一:图片地址返回完全
				<ul v-for="(item,index) in list1" :key="item.id">
					<img :src="item.imgUrl" alt="">
				</ul>
				
				情况二:图片地址返回不完全
				<ul v-for="(item,index) in list2" :key="item.id">
					<img :src=" 'http://134.175.154.93:8888/group1/' + item.imgUrl" alt="">
				</ul>
 	
	

1.基本数据类型之间的转换 (工具:xshell)

 1)其他数据类型转换为数字类型
 	+-
 	Number()
 	1.字符串转数字类型
 		var str = '123';
		//方法一
		var num1 = +str;
		//方法二
		var num2 = Number(str);

		console.log('str',typeof(str));	//string
		console.log('num1',typeof(num1)); //number
		console.log('num2',typeof(num2)); //number

		---

		var str = 'hello world';
		var num = Number(str);
		console.log(num);	// NaN
		console.log(typeof(num));	// number
	2.布尔类型转换数字类型
		var a = true;
		var b = false;

		var num1 = Number(a);
		var num2 = Number(b);

		console.log('num1',num1);	//1
		console.log('num2',num2);	//0
	3.null.undefined转换数字类型
		var a = null;
		var num = +a;
		console.log(num); //0

		---

		var a = undefined;
		var num = +a;
		console.log(num); //NaN
	4.parseInt/parseFloat
		var a = 1.123;

		var num1 = parseInt(a);
		var num2 = parseFloat(a);

		console.log('num1',num1); //1
		console.log('num2',num2); //1.123
		
2)其它数据类型转换为字符串类型
	''""
	String()
	toString()   null,undefined不可以调用
	var a = 1;

	var str1 = 'a';
	var str2 = String(a);
	var str3 = a.toString();

	console.log('str1',typeof(str1)); //string
	console.log('str2',typeof(str2)); //string
	console.log('str3',typeof(str3)); //string

3)其它数据类型转换为布尔类型
	!!
	Boolean()
	1.数字类型转布尔类型
		var a = 1;
		var b = 0;

		var bn1 = !!a;
		var bn2 = Boolean(a);
		var bn3 = !!b;

		console.log('bn1',bn1);	//true
		console.log('bn2',bn2); //true
		console.log('bn3',bn3); //fasle
	2.字符串类型转布尔类型
		var str1 = 'hello';
		var str2 = '';

		var bn1 = !!str1;
		var bn2 = !!str2;

		console.log('bn1',bn1);	//true
		console.log('bn2',bn2); //false
	3.null、undefined转布尔类型
		返回值都为false

2.流程控制语句

1)分支语句
	做了不同的选择,会有不同的后果,满足不同的条件,会执行不同的代码。
		if(){}
	
		if(){} else {}
	
		if(){} else if(){} else {}
	
		switch-case
	
		var password = 123321;
		if(password == '123321'){
			console.log('密码正确')
		}
	
		var age = 18;
		if(age >= 18){
			console.log('成年人')
		} else {
			console.log('未成年')
		}
	
		==>
	
		三目运算符
		age >= 18 ? '成年人' : '未成年'
	
	
		var name = '坚果云'
	
		if(name == '蓝奏云'){
			console.log('下载速度为11.42MB/s')
		} else if (name == '坚果云'){
			console.log('下载速度为7.34MB/s')
		} else if (name == '天翼云盘'){
			console.log('下载速度为3.02MB/s')
		} else {
			console.log('下载速度为3.02kb/s')
		}
	
		---
		var name = '百度网盘';
	
		switch(name){
		    case '蓝奏云':
		        console.log('下载速度为11.42MB/s');
		        break;
		    case '坚果云':
		        console.log('下载速度为7.34MB/s');
		        break;
		    default:
		        console.log('您使用的是百度网盘')
		}
		注意:
			1、在switchcase之间,不能加其他代码
			2、每一次判断条件结束的时候,都要加break,以跳出switch判断
				如果没有加break,代码会一直往下继续执行,直到遇到下一个break或者是default,才跳出switch判断

2)循环语句
	循环的三要素:初始化条件,结束判定条件,迭代
	for(){}
	while
	do-while
	1.for循环
		for(初始化条件;结束判定条件;迭代){
					//循环体
				}

				如何实现1-100累加的和?
					初始化条件		var i=1
					结束判定条件		i <= 100
					迭代				i++

					var result = 0;
					for(var i=1;i<=100;i++){
					   result = result + i;
					   //result += i;
					}
					console.log(result);	//5050

					result = 0;
					i = 1
					i<=100true
					result = 0 + 1 = 1
					i = 2

					i<=100true
					result = 1 + 2 = 3
					i = 3

					...

					i = 100

					i<=100true
					result = 4950 + 100 = 5050
					i = 101

					i<=100false,跳出for循环

	2.while循环(前置判断循环)
			初始化条件
			while(判定结束条件){
				循环体
				迭代
			}

			var result = 0;
			var i = 1;
			while(i<=100){
			    result = result + i;
			    i++;
			}
			console.log(result);
	3.do-while循环(后置判断循环)
			初始化条件
			do {
				循环体
				迭代
			} while(判定结束条件)
	
			var result = 0;
			var i = 1;
			do {
			    result += i;
			    i++;
			} while(i<=100)
			console.log(result);

3.对象 万物皆可对象

1)介绍
	属于复杂的数据类型(引用数据类型),一般情况下,一个对象当中可以包含多个属性和方法。
	
2)对象的规则
	1.对象以{}作为边界
	2.一个对象当中可以包含多个属性和方法(方法是一个特殊的属性)
	3.每个属性与属性之间通过逗号(,)分隔
	4.属性名与属性值之间通过冒号(:)分隔
	5.属性名可以不适用引号,但是如果属性名包含特殊字符(空格),需要使用引号
	6.属性值一般是具体的值(常量),也可以是变量
	7.最后一个属性值后面不需要加逗号
		var name = 'jackson'

		var obj = {
			name:this.name,
			age:25,
			gender:'male',
			phone:13412741213,
			sayMyWork:function(){
				console.log('我在阿里巴巴上班')
			},
			'hello wolrd':function(){

			}
		}
		
3)对象的创建方式
	1.对象字面量
		var obj = {}

		var obj = {
			name:'xpf',
			age:25,
			gender:'male'
		}
	2.Object构造函数
		var obj = new Object();
		obj.name = 'xpf';
		obj.age = 25;
		obj.gender = 'male';
		动态新增属性名

		值传递和引用传递

4)对象的访问
	点访问符 .
		var obj = {
			name:'xpf',
			age:25,
			gender:'male'
		}
		console.log(obj.gender);	//male

	中括号访问符	[]
		var obj = {
		    name:'xpf',
		    age:25,
		    gender:'male'
		}

		var gender = 'gender'
		console.log(obj[gender]); //male

		console.log(obj['gender']); //male

	思考:如何访问属性hello
		var obj = {
			phone:13412741213,
			'hello':function(){
				console.log('hello world')
			}
		}
	答:obj.hello(); 

5)删除属性
	var obj = {
	    name:'xpf',
	    age:25,
	    gender:'male'
	}
	console.log(obj); // { name: 'xpf', age: 25, gender: 'male' }
	delete obj.age;
	console.log(obj); // { name: 'xpf', gender: 'male' }
			

4.序列化与反序列化

JSON.stringify()  序列化
JSON.parse()  反序列化
 序列化:  将json格式数据转换为字符串
 	var obj = {
		name:'xpf',
		age:25,
		gender:'male'
	}
	var str = JSON.stringify(obj); 
	console.log(str); // '{"name":"xpf","age":25,"gender":"male"}'
	console.log(typeof(str)); // string
	
 //在外层使用了双引号,内层再去使用引号的时候,一定要使用单引号
 反序列化:将字符串转换为json格式的数据
 	var str = '{"name":"xpf","age":"25","gender":"male"}';
	var obj = JSON.parse(str);
	console.log(str);
	console.log(typeof(str));
	console.log('---');
	console.log(obj);
	console.log(obj.gender);
	console.log(typeof(obj));
拓展案例:
	从A页面跳转到B页面的同时,我想将A页面当中的某一对象放在浏览器的地址栏上

5.对象的遍历 for-in

	var obj = {
		 name:'xpf',
		    age:25,
		    gender:'male',
		    'hello world':function(){
		        console.log('hello world')
		    }
	}
	for(var key in obj){
	    console.log(key);
	    console.log(obj[key]); // 打印所有的属性值
	}
	key表示当前对象的所有属性名,每次从obj中获取一个属性名赋值给key,然后执行循环体
	
	for(var key in obj){
	    if(key == 'hello world'){
	        console.log(obj[key]); // 只打印属性名为hello wolrd的属性值
	    }
	}

6.in关键字

	prop in obj
	in运算符能够检测左侧操作数(prop)是否是右侧操作数(obj)的成员,左侧操作数是一个字符串,右侧操作数是一个对象
	var obj = {
	    name:'xpf',
	    age:25,
	    gender:'male'
	}
	console.log('name' in obj); // true
	console.log('age' in obj); // true
	console.log('sayName' in obj); // false

7.函数

 this、闭包、自执行函数、匿名函数
 1)函数的用处
	1.使用函数封装具有某些功能的代码,执行特定的功能
	arr.sort()   排序
	arr.reverse()  反转
	jQuery
	loadsh
	moment
	...
    第三方插件
	2.使用函数封装创建对象的模板(构造函数)面向对象
	
 2)函数的定义
	1.函数声明
		function 函数名(){
			函数体
		}
		function sayHello(){
			console.log('hello world');
		}
	2.函数表达式
		var 函数名 = function(){
			函数体
		}
		var sayHello = function(){
			console.log('hello world');
		}

 3)函数调用
	函数名();
	函数名.call(this,实参列表);
	函数名.apply(this,实参数组);

	function sayMessage(name,age,gender){
	    console.log(name)
	    console.log(age)
	    console.log(gender)
	}

	var name = 'xpf';
	var age = 25;
	var gender = 'male';
	//函数名(实参);
	sayMessage(name,age,gender);
	//函数名.call(this,实参列表);
	sayMessage.call(this,name,age,gender);
	//函数名.apply(this,实参数组);
	sayMessage.apply(this,[name,age,gender])

拓展:
	1、函数使用括号与不适用括号的区别
		1.带括号
		2.不带括号

		错误代码:
			function sayHello(){
				console.log('hello world');
			}
			//在这一行代码,实际上已经调用了函数sayHello,打印出了hello world,但是,由于函数没有使用return,所以该函数没有返回值
			var info = sayHello();	
			var obj = {
				say:info
			}
			console.log(obj.say); // undefined

		正确代码:
			function sayHello(){
				console.log('hello world');
			}
			var info = sayHello;	
			var obj = {
				say:info
			}
			console.log(obj.say); // [Function: sayName]
	2、console.log与return的区别
		1.使用console.log的时候,返回的是一个undefined
		2.使用return的时候,调用了函数会有返回值

		错误代码:
			function sayHello(){
				console.log('hello world');
			}
			//在这一行代码,实际上已经调用了函数sayHello,打印出了hello world,但是,由于函数没有使用return,所以该函数没有返回值
			var info = sayHello();	
			var obj = {
				say:info
			}
			console.log(obj.say); // undefined
		正确代码:
			function sayHello(){
			    return 'hello world';
			}
			var info = sayHello();
			var obj = {
			    say:info
			}
			console.log(obj.say,'---');

8.函数声明的提升

1.什么叫提升
	函数的声明和变量的声明会从它们的代码中出现的位置被移动当前作用域的最上方,进行执行,这个过程叫提升。
	1)	a = 1;
		var a;
		console.log(a); // 1
		
		=>
		
		var a;
		a = 1;
		console.log(a); 
	2) console.log(b);	// undefined
		var b = 2;

		=>

		var b;
		console.log(b);	// undefined
		b = 2;

2.函数的提升
	info();
	function info(){
	    var c = 3;
	    console.log(c);
	}

	=>

	function info(){
	    var c = 3;
	    console.log(c);  // 3
	}
	info();

3.函数表达式的提升
	fun();
	var fun = function(){
	    var d = 4;
	    console.log(d);
	}

	=>

	var fun;
	fun();
	fun = function(){
	    var d = 4;
	    console.log(d);
	}
	会报错fun is not a function

4.函数优先
	var foo = function(){
	    console.log(2);
	}

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

	foo();

	=>

	function foo(){
	    console.log(1);
	}
	var foo;
	foo = function(){
	    console.log(2);
	}

	foo(); // 2
	函数声明和函数表达式都会被提升,但是函数声明是在函数表达式之前被提升,也叫函数优先

9.值传递和引用传递

值传递
	var a = 3;
	var b = a;

	b++;
	console.log(a);	// 3
	console.log(b); // 4
	
引用传递
	var obj = {
	    name:'xpf',
	    age:25,
	    gender:'male'
	}
	var obj2 = obj
	obj2.age++;

	console.log(obj); // { name: 'xpf', age: 26, gender: 'male' }
	console.log(obj2); // { name: 'xpf', age: 26, gender: 'male' }
   //obj2中的数据改变,obj会跟着变化
   
存储:
	1) 基本数据类型保存在栈内存当中,它们的值都有固定的大小,通过按置访问
	2) 引用数据类型是保存在堆内存中的对象,值的大小不确定,栈内存当中存放的是该对象的访问地址,JavaScript不允许直接访问堆内存中的值,因此操作的实际都是对象的引用
	
复制:
	1) 基本数据类复制时,系统会自动为新的变量分配一个新的值,最后这些变量都是相互独立互不影响
	2) 引用数据类型复制时,同样会为新的变量分配一个新的值,保存在栈内存中,不同的是,这个值仅仅是引用数据类型的一个地址指针
注意:堆内存中,同一个值可以被多个引用地址指向,但是同一个引用地址不能同时指向多个堆内存中的值

10.函数内部属性

  只能在函数运行的时候才能确定的属性,并且只能在函数内访问
	function add(a,b){
		console.log(a,'a');
		console.log(b,'b');
		console.log(arguments,'arguments');
		return a+b;
	}
	var result = add(2,3,4);
	console.log(result);

	1. 形参 (接收参数的快捷方式)
		a -> 2
		b -> 3
	2. arguments (接收参数的真正所在)
		类数组对象 -> 数组
		当前函数接收的所有参数存储的地方
		[Arguments] { '0': 2, '1': 3, '2': 4 }
		length
	3. this 当前对象 this的指向性问题
			this的取值与函数的调用方式有关
				函数名(实参); 
				函数名.call(this,实参列表);
				函数名.apply(this,实参数组);

			function sayAge(){
			    console.log(this);
			}
			var obj1 = {
			    name:'xpf',
			    sayName:function(){
			        console.log(this.name);
			    }
			}
			var obj2 = {
			    name:'zhangsan',
			    sayName:function(){
			        console.log(this.name);
			    }
			}

			sayAge(); // this指向当前global对象
			obj1.sayName(); // xpf this指向obj1对象
			obj2.sayName(); // zhangsan this指向obj2对象

			结论一:
				如果函数使用了 () 调用,那就看一下括号前面是不是函数名,如果是,再看函数名前面有没有对象
					有对象,this指向该对象
					没有对象	
						nodejs	this指向global对象
						浏览器 	this指向window对象

			var pig = {
			    words:'哼哼',
			    sound:function(){
			        console.log(this.words);
			    }
			}

			var dog = {
			    words:'汪汪'
			}
			pig.sound(); // 哼哼
			pig.sound.call(dog); // 汪汪
			通过使用call,可以将原本指向pig的this,指向了dog

			继承

			结论二:(更改this指向)
				如果通过call、apply来调用,this的指向为用户手动指向的对象
				

11.闭包

	是指有权访问另一个函数作用域中的变量的函数,闭包可以让你从内部的函数访问到外部函数中的变量
	形式:	函数中包含另一个函数
		function fn1(){
		    var name = 'xpf';
		    //fn2就是一个闭包
		    function fn2(){
		        var age = 25;
		        //使用父函数中声明的变量
		        console.log(name);
		    }
		    fn2();
		}
		fn1();
	
	参考:
		https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
		JavaScript高级程序设计 第七章
		

12.立即执行函数,匿名函数

(function(){
	console.log(1)
	})();
	
	(function(a,b){
	    console.log(a+b)
	})(1,2);
	

13.数组

1)作用(特点)
	1.存放多个数据的集合
	2.数组的边界[]
	3.数组的组成称为元素/4.元素与元素之间通过逗号(,)来分割
	5.元素的数据类型没有限制
	
2)定义方式
	1.数组字面量
		var arr1 = [];
		console.log('arr1',arr1);
		var arr2 = [1,'hello world',null,undefined,function(){},{name:'xpf'}];
		console.log('arr2',arr2);
		
	2.Array构造函数
		var arr3 = new Array();
		console.log('arr3',arr3); // []

		var arr4 = new Array(3,4);
		console.log('arr4',arr4); // [3,4]

		var arr5 = new Array(1,'hello world',null);
		console.log('arr5',arr5);

	注意:如果传递的是一个数字,则会按照该数字创建指定项数的数组,但是没有内容,也就是只定义了数组的长度
		 var arr = new Array(3);
		 console.log(arr);//[3 empty items] 等同于 var arr = [,,];
		 只希望数组中包含一个数字3,使用数组字面量去创建
		 var arr = [3];
	
3)数组的访问
	数组名[索引]
	索引:从0开始
	一维数组
	二维数组	[[1,2,3],[4,5,6]]
	var arr = ['hello','world','xpf'];
	console.log(arr[0]); // hello
	console.log(arr[1]); // world
	console.log(arr[2]); // xpf
	注意:如果指定索引的位置上没有值,返回undefined
	var arr = ['hello','world','xpf'];
	console.log(arr[3]); // undefined
	
4)数组的属性
	数组也是一个对象,length表示数组的长度(个数)
	var arr1 = ['hello','world','xpf'];
	var arr2 = new Array(3);
	var arr3 = [];

	console.log(arr1.length); // 3
	console.log(arr2.length); // 3
	console.log(arr3.length); // 0
	
	拓展:新增指定数组的项
		 length = 最后一项的索引index + 1;
		 数组的长度始终比数组的最后一项的索引大1
		 var arr = ['hello','world','xpf'];
		 arr1[arr.length] = '你好';
		 arr1[arr.length] = '张三';

		 console.log(arr);

14.数组的遍历

1for循环
2while循环
3do-while循环
	var arr = ['hello','world','xpf'];
	//将数组的长度赋值给length变量
	var length = arr.length;
	for(var i=0;i<length;i++){
		//i是当前遍历数组的索引
	    console.log(i);
	    //arr[i]就是当前遍历数组的每一项
	    console.log(arr[i],'---');
	}

	
4for-in 增强for循环
	var arr = ['hello','world','xpf'];
	for(var key in arr){
		//key是当前遍历数组的索引
	    console.log(key);
	    //arr[key]就是当前遍历数组的每一项
	    console.log(arr[key]);
	}
	

15.判断是否为数组

	Array.isArray()

	var arr = [1,2,3,4];
	var obj = {
	    name:'xpf',
	    age:25,
	    gender:'male'
	}
	console.log(Array.isArray(arr)); // true
	console.log(Array.isArray(obj)); // false
	
	拓展:
	instanceof  引用数据类型
		判断某一个变量是否是某一个构造函数的实例
	typeof	基本数据类型
	
	var arr = [1,2,3,4];
	console.log(arr instanceof Array); // true
	console.log(arr instanceof Object); // true
	原型链
		爷爷奶奶		
		Object构造函数
		父母			
		Array构造函数、原型
		你			
		arr实例
		

16.数组API

	数组构造函数原型中的方法,即数组实例都可以调用
	Array.prototype.push()
	Array.prototype.pop()
	Array.prototype.shift()
	Array.prototype...
	
	api
	   	含义;参数;返回值
	1)添加元素,删除元素相关【改变了原数组的】
	   push()
	   	含义:在数组的最后添加元素
	   	参数:要添加的元素
	   	返回值:返回新增了元素之后的数组的长度

		添加一个元素
			var arr = [1,2,3];
			var name = 'xpf';
			var result = arr.push(name);
			console.log(arr); //[1,2,3,'xpf']
			console.log(result); //4
		添加多个元素
			var arr = [1,2,3];
			var name = 'xpf';
			var age = 25;
			var gender = 'male';
			var result = arr.push(name,age,gender);

			console.log(arr); // [ 1, 2, 3, 'xpf', 25, 'male' ]
			console.log(result); // 6
			
	   pop()
	    含义:从数组的最后取出一个元素
		参数:无
		返回值:返回被删除的元素

		var arr = [1,2,3,4,'zhangsan'];
		var result = arr.pop();

		console.log(arr); // [1,2,3,4]
		console.log(result); // zhangsan
		注意:就算在pop()的小括号里面加了参数,也没效果

		var arr = [1,2,3,4,'xpf'];
		arr.pop();
		arr.pop();
		arr.pop();

		console.log(arr); // [1,2]
	  
	  shift()
		含义:将数组中第一个元素删除
		参数:无
		返回值:被删除的元素

		var arr = ['hello','world','xpf','tom'];
		var result = arr.shift();

		console.log(arr); // [ 'world', 'xpf', 'tom' ]
		console.log(result); // hello
	
	  unshift()
		含义:将元素添加到数组的最前面
		参数:要新增的元素
		返回值:新增了元素之后的新数组的长度
	
		var arr = ['hello','world','xpf','tom'];
	
		var age = 25;
		var gender = 'male';
		var result = arr.unshift(age,gender);
	
		console.log(arr); // [25,'male','hello','world','xpf','tom']
		console.log(result); // 6
	
	2)排序方式【改变原数组】
		sort()
		var arr = [2,4,1,5,3];
		console.log(arr.sort()); // [1,2,3,4,5]
		
		买家秀和卖家秀
			需要对一下数组进行排序,从小到大
				排序前:var arr = [3,2,1,12,21];
				排序后:arr = [1,2,3,12,21];

			代码一:
				var arr = [3,2,1,12,21];
				var result = arr.sort();
				console.log(result);	// [1,2,3,12,21]
			代码二:
				使用比较器函数
				arr.sort(比较器函数)
					比较器函数也称为匿名函数,可以接两个参数a,b
						当a>b时返回1,从小到大排序
						当a<b时返回-1,从大到小排序

				var arr = [3,2,1,12,21];
				var result = arr.sort(function(a,b){
				    if(a>b){
				        return 1;
				    } else {
				        return -1;
				    }
				});
				console.log(result); // [1,2,3,12,21]

	3)数组序列化【不改变数组】
		如何将一个数组转换为字符串?
		var arr = [1,2,3];
		->
		1,2,3
		
		1.toString()
			含义:将数组转换为字符串,数组中的元素通过逗号连接
			参数:无
			返回值:转换后的字符串
			var arr = [1,2,3,4];

			var result = arr.toString();
			console.log(arr,'arr'); // [1,2,3,4]
			console.log(result); // 1,2,3,4
			console.log(typeof(result)); // string
		2.join()
			含义:将数组转换为字符串
			参数:可有可无
			返回值:转换后的字符串
			var arr = [1,2,3,4];
				->
				1234
				1 2 3 4
				1-2-3-4
				1+2+3+4

			var arr = [1,2,3,4];

			var result1 = arr.join();
			var result2 = arr.join('');
			var result3 = arr.join(' ');
			var result4 = arr.join('-');
			var result5 = arr.join('*');

			console.log(arr); // [1,2,3,4]
			console.log(result1); // 1,2,3,4
			console.log(result2); // 1234
			console.log(result3); // 1 2 3 4
			console.log(result4); // 1-2-3-4
			console.log(result5); // 1*2*3*4
		3.JSON.stringify()
			含义:将数组转换为json字符串
			参数:需要转化的数组
			返回值:转换后的json字符串
			var arr = [1,2,3,4,5];
			var result = JSON.stringify(arr);
	
			console.log(arr); // [1,2,3,4,5]
			console.log(Array.isArray(arr)); // true
			console.log(result); // '[1,2,3,4,5]'
			console.log(typeof(result)); // string
		
	4)数组截取方法
		1.concat()【不改变原数组】
			含义:将参数中的数组和使用该方法的数组合并为一个数组
			参数:一个或多个数组
			返回值:合并后的数组
			var arr1 = [1,2,3];

			var arr2 = arr1.concat([4,5,6]);
			var arr3 = arr1.concat(['hello','world'],['xpf','tom']);
			console.log(arr1); // [1,2,3]
			console.log(arr2); // [1,2,3,4,5,6]
			console.log(arr3); // [1,2,3,'hello','world','xpf','tom']
		2.slice()【不改变原数组】
			含义:从使用了该方法的数组中截取一个子数组
			参数:一个或者两个数字
			返回值:返回截取到的子数组

			一个参数:
				var arr1 = [1,2,3,4,5];

				var arr2 = arr1.slice(2);
				var arr3 = arr1.slice(5);
				console.log(arr1); // [1,2,3,4,5]
				console.log(arr2); // [3,4,5]
				console.log(arr3); // []

				如果只传递了一个参数,截取到的就是索引从该位置开始之后所有的项,做为新数组,如果该值超过了原数组的最大索引,返回的将是一个空数组

			两个参数:
				slice(a,b)
					a -> 起始位置
					b -> 结束位置
				如果传递的是两个参数,截取子数组的时候,包含起始位置,不包含结束位置
				var arr1 = [1,2,3,4,5];
				var arr4 = arr1.slice(2,3);
				console.log(arr4); // [3]

			三个或者多个参数:
				多余的参数没有效果
		3.splice() 【改变原数组的值】
			含义:从使用了该方法的数组中删除、新增、修改操作
			参数:一个或者多个
			返回值:删除的元素组成的新数组

			一个参数:
				var arr1 = [1,2,3,4,5];
				var arr2 = arr1.splice(1);

				console.log('arr1',arr1); // [1]
				console.log('arr2',arr2); // [2,3,4,5]

				删除该位置之后的所有元素,被删除的元素组成一个新数组

			两个参数:
				var arr1 = [1,2,3,4,5];
				var arr2 = arr1.splice(1,3);

				console.log('arr1',arr1); // [1,5]
				console.log('arr2',arr2); // [2,3,4]

				删除第一个参数之后,项数为第二个参数的元素,被删除的元素组成一个新的数组

			三个参数:
				var arr1 = [1,2,3,4,5];
				var arr2 = arr1.splice(1,3,9);

				console.log('arr1',arr1); // [1,9,5]
				console.log('arr2',arr2); // [2,3,4]

				删除第一个参数与第二个参数之间的项(起始位置和结束位置都包含),被删除的元素组成一个新的数组,同时将第三个参数放到被删除的位置上

	5)数组迭代方法
		forEach(function(){})
			用法:遍历当前数组
			参数:function(item,index,arr){}
				每遍历一次,这个匿名函数就会被调用一次,forEach将当前遍历的元素,索引,当前数组,作为实参传递给这个匿名函数
			返回值:无
			var arr = ['hello','world','zhangsan'];

			var result = arr.forEach(function(item,index,arr){
			    console.log('item',item); // 当前遍历的数组中的每一个元素
			    console.log('index',index); // 当前遍历的数组的每一个元素的索引
			    console.log('arr',arr); // 当前遍历的数组
			})
			console.log(result); // undefined

		every()	
			用法:判断一个数组中的所有元素是否都满足给定的条件
			参数:function(item,index,arr){}
			返回值:
				当每次回调函数返回值都为true的时候,every方法的返回值才为true
				只要回调函数有一次的返回值为false,every方法都返回false
				var arr = [1,2,3,4,5];
				var result = arr.every(function(item,index){
				    return item > 3;
				});
				console.log(result); // false

		some()
			用法:判断数组中是否有满足条件的元素
			参数:function(item,index,arr){}
			返回值:
				只要回调函数有一次的返回值为true,some方法都返回true
				var arr = [1,2,3,4,5];
				var result = arr.some(function(item,index){
				    return item > 3;
				});
				console.log(result); // true

		filter()
			用法:筛选数组中满足条件的元素(过滤)
			参数:function(item,index,arr){}
			返回值:
				只要有满足给定条件的元素时,返回这些元素组成的数组

				var arr = [1,2,3,4,5];
				var result = arr.filter(function(item,index){
				    return item > 3;
				});
				console.log(result); // [4,5]

		map()
			用法:使用给定条件处理数组(映射)
			参数:function(item,index,arr){}
			返回值:
				返回一个处理后的数组

				var arr = [1,2,3,4,5];
				var result = arr.map(function(item,index){
				    return item > 3;
				});
				console.log(result); // [fasle,false,false,true,true]

				var arr = [1,2,3,4,5];
				var result = arr.map(function(item,index){
				    return item + 3;
				});
				console.log(result); // [4,5,6,7,8]

	6)类数组对象转换为数组
		jQuery
		1.[...arguments],该方法只对拥有迭代器的有效
		2.Array.from(arguments)
		3.Array.prototype.slice.call(arguments)
		function sayName(a,b){
		    console.log([...arguments]);
		    console.log(Array.from(arguments));
		    console.log(Array.prototype.slice.call(arguments));
		}

		sayName(1,2,3);

		obj是我们自己创建的一个具有迭代器的类数组对象
		var obj ={
			0:'a',
			1:'b',
			length:2,
			[Symbol.iterator]:Array.prototype[Symbol.iterator]
		}
		console.log([...obj]); // ['a','b']


17.正则表达式

1)含义
	当搜索文本中的数据时,可以使用搜索模式来描述搜索的内容。也就是说,正则表达式回去查找字符串符合某个模式的部分
	->
	前端中的表单验证
		手机号:15700...
		邮箱:zhangsan@163.com

2)正则表达式定义方式
	1.构造函数模式
		var pattern = new RegExp('正则表达式','正则表达式修饰符');
		var pattern = new RegExp('ab','img');
		console.log(pattern); // /ab/gim

	2.正则表达式字面量
		var pattern = /正则表达式/正则表达式修饰符
		var pattern = /ab/img;
		console.log(pattern); // /ab/gim
	正则表达式修饰符:
	i:ignoreCase 	执行对大小写不敏感的匹配(忽略大小写)
	m:multiline		执行多行匹配
	g:global		执行全局匹配(查找所有匹配,而不是在找到第一匹配到的字符之后停止匹配)
	
3)正则表达式原型属性
	RegExp.prototype.xxx
		RegExp.prototype.global		布尔值,表明这个正则表达式是否带有修饰符g
		RegExp.prototype.ignoreCase		布尔值,表明这个正则表达式是否带有修饰符i
		RegExp.prototype.multiline		布尔值,表明这个正则表达式是否带有修饰符m
		RegExp.prototype.source		正则表达式的字符串表示
		RegExp.prototype.flags		正则表达式修饰符的字符串表示
		var pattern = /ab/img;

		console.log(pattern.global); // true
		console.log(pattern.ignoreCase); // true
		console.log(pattern.multiline); // true
		console.log(pattern.source); // 'ab'
		console.log(pattern.flags); // 'img'

		var pattern = /ab/im;

		console.log(pattern.global); // false
		console.log(pattern.ignoreCase); // true
		console.log(pattern.multiline); // true
		
4)正则表达式原型方法
	RegExp.prototype.xxx
		1.RegExp.prototype.test()
			用法:检测一个字符串是否匹配某个模式
			参数:待检测的字符串
			返回值:如果被检测的字符串满足正则表达式的匹配模式,返回true,否则返回false
			var pattern = /abc/img;
			var str = 'hello world abc';
			var result = pattern.test(str);
			console.log(result); // true

			var pattern = /abc/img;
			var str = 'hello world ab c';
			var result = pattern.test(str);
			console.log(result); // false

			会从hello world abc的第一个字母开始,一个一个检测是否有a,当遇到a的时候,去判断a的后面是否是b,如果是,再去判断b的后面是否是c,如果是,返回true
		2.RegExp.prototype.exec()
			用法:检测字符串中的正则表达式的匹配 -> 从str中查找出满足正则表达式的字符串
			参数:待检测的字符串
			返回值:数组或null
				如果正则表达式中有'g'修饰符,这时,在pattern中会维护一个lastIndex属性,记录下一次开始的位置,当第二次执行exec方法,会从lastIndex开始检索
				如果正则表达式中没有'g'修饰符,这是,在pattern中不会维护一个lastIndex属性,当第二次执行exec方法时,会从开始位置检索
			有g修饰符 --> 维护lastIndex
				执行了一次exec方法
					var pattern = /abc/img;
					var str = 'ababc ac ab abcd we';

					console.log(pattern.exec(str));
					console.log(pattern.lastIndex); // 5 下一次检索开始的位置

				执行了两次exec方法
					var pattern = /abc/img;
					var str = 'ababc ac ab abcd we';

					console.log(pattern.exec(str));
					console.log(pattern.lastIndex); // 5 下一次检索开始的位置

					console.log(pattern.exec(str));
					console.log(pattern.lastIndex); // 15 下一次检索开始的位置

				执行了三次exec方法
					var pattern = /abc/img;
					var str = 'ababc ac ab abcd we';

					console.log(pattern.exec(str));
					console.log(pattern.lastIndex); // 5

					console.log(pattern.exec(str));
					console.log(pattern.lastIndex); // 15

					console.log(pattern.exec(str)); // null
					console.log(pattern.lastIndex); // 0

			没有g修饰符 --> 不会维护lastIndex
				var pattern = /abc/img;
				var str = 'ababc ac ab abcd we';

				console.log(pattern.exec(str));
				console.log(pattern.lastIndex); // 0

				console.log(pattern.exec(str));
				console.log(pattern.lastIndex); // 0

			错误代码:只打印了两次结果,并没有调用两次exec方法
				var pattern = /abc/img;
				var str = 'ababc ac ab abcd we';
				var result = pattern.exec(str);

				console.log(result);
				console.log(pattern.lastIndex); // 5

				console.log(result);
				console.log(pattern.lastIndex); // 5

			此时,我需要匹配abcd或者abce,即找出字符串中满足两种条件的字符串
				|  表示从左右两侧选择以重符合条件的字符串()
				var pattern = /abc(d|e)/img;
				var str = 'ababce ac ab abcd we';

				console.log(pattern.exec(str)); // abce
				console.log(pattern.exec(str)); // abcd

			上述代码,找出两个满足条件的字符串时,需要调用两次exec方法

			思考:如果说,需要找到字符串中所有满足条件的字符串,该如何实现?

			答案:使用循环	
				while(){}

				var pattern = /abc(d|e)/img;
				var str = 'ababce ac ab abcd we';

				console.log(pattern.exec(str));
				console.log(pattern.exec(str));
				console.log(pattern.exec(str)); // null
				说明第三次调用exec方法时,该字符串中已经没有满足条件的字符串

			-->	循环时,调用exec方法,直到exec() == null时,结束循环
				var pattern = /abc(d|e)/img;
				var str = 'ababce ac ab abcd we';

				var temp = [];
				while(result = pattern.exec(str)){
				    temp.push(result);
				}

				console.log(temp); // 二维数组

			思考:如何将满足条件的字符串单独放到一个数组中 --> ['abcd','abce']
				var pattern = /abc(d|e)/img;
				var str = 'ababce ac ab abcd we';

				var temp = [];
				while(result = pattern.exec(str)){
				    temp.push(result[0]);
				}

				console.log(temp); // ['abcd','abce']

			match()	-->  字符串方法
				用法:可在字符串内检索指定的值,找到一个或多个正则表达式的匹配
				var pattern = /abc(d|e)/img;
				var str = 'ababce ac ab abcd we';

				console.log(str.match(pattern)); // ['abcd','abce']

5)正则表达式
	1.字符类
		.			匹配任何单个字符
		
		\d			匹配任意的数字 等价于[0-9]
					/\d/img;  =>  /[0-9]/img;
		[0-9]		匹配任意的数字
		\D			匹配任意的非数字 等价于[^0-9]
		[^0-9]		匹配任意的非数字
					/\D/img;  =>  /[^0-9]/img;
					
		\w 			匹配字符,等价于[a-zA-Z0-9_]		
		\W 			匹配非字符,等价于[^a-zA-Z0-9_]

		^			匹配开始的字符
					^[0-9]   匹配以数字作为开始
		$			匹配结束的字符
					[0-9]$	 匹配以数字作为结束

		\s  		匹配空白符,tab、space、return...
		\S 			匹配非空白字符
			案例一:
					匹配['123']
						var str = 'abc123.abc.d1234';
						//var pattern = /\d\d\d/img;
						var pattern = /[0-9][0-9][0-9]/img;
	
						console.log(str.match(pattern)); // ['123','123']
	
					匹配['123.']
						错误代码:
							var str = 'abc123.abc.d1234';
							var pattern = /\d\d\d./img;
	
							console.log(str.match(pattern)); // ['123.','1234']
							注意:此处的.不表示. 而是表示匹配任意的单个字符
	
						正确代码:
							转义,使用\进行转义(. /)
							var str = 'abc123.abc.d1234';
							var pattern = /\d\d\d\./img;
	
							console.log(str.match(pattern)); // ['123.']
	
					匹配['123.','abc.']
						var str = 'abc123.abc.d1234';
						var pattern = /\w\w\w\./img;
						//var pattern = /[a-zA-Z0-9_][a-zA-Z0-9_][a-zA-Z0-9_]\./img;
	
						console.log(str.match(pattern)); // ['123.','abc.']
	
				案例二:
					var str = 'abcd\n1ac\nqwer\n2zxcv';
					console.log(str);
	
					\n表示换行
						abcd
						1ac
						qwer
						2zxcv
	
					匹配以0-9开始的字符
						多行匹配 m
							var str = 'abcd\n1ac\nqwer\n2zxcv';
							var pattern = /^[0-9]/img;
	
							console.log(str.match(pattern)); // ['1','2']
						取消多行匹配
							var str = 'abcd\n1ac\nqwer\n2zxcv';
							var pattern = /^[0-9]/ig;
	
							console.log(str.match(pattern)); // null
							只对第一行字符串进行了匹配
	
					匹配以d或r结束的字符
						正确代码
							var str = 'abdc\n1ac\nqwer\n2zxcv';
							var pattern = /(d|r)$/img;
	
							console.log(str.match(pattern)); // ['r']
	
						错误代码
							var str = 'abdc\n1ac\nqwer\n2zxcv';
							var pattern = /d|r$/img; // 解析成匹配d或者以r结束
	
							console.log(str.match(pattern)); // ['d',r']
	
				案例三:	
					判断一个手机号位数 
					11位 以1开始
						情况一:没加结束条件 $
							var str = '15719344291';
							var pattern = /^1\d{10}/img;
	
							console.log(pattern.test(str)); // true
	
							var str = '157193442912qwer';
							var pattern = /^1\d{10}/img;
	
							console.log(pattern.test(str)); // true
							只要字符串满足了以1开始,后面为10个数字的条件之后,不管字符串后面接的什么内容,都会返回true
						情况二:加了结束条件 $
							var str = '15719344291';
							var pattern = /^1\d{10}$/img;
	
							console.log(pattern.test(str)); // true
	
							var str = '157193442912';
							var pattern = /^1\d{10}$/img;
	
							console.log(pattern.test(str)); // false
							只有当字符串满足以1开始,后面时10个数字的条件,才返回true,多一位少一位都不行
		
	2.分组
		()代表分组,在正则表达式中用()包裹起来的内容代表了一个分组
		案例一:
			var str1 = 'I come from anhui';
			var str2 = 'I come from hubei';
			var pattern = /I come from (jiangsu|anhui|beijing)/img;

			console.log(pattern.test(str1)); // true
			console.log(pattern.test(str2)); // false

		案例二:
			时间格式 2020-04-26
				var str = '2020-04-26';
				var pattern = /(\d{4})-(\d{2})-(\d{2})/img;

				console.log(pattern.test(str)); // true

				var str = '2020/04/26';
				var pattern = /(\d{4})-(\d{2})-(\d{2})/img;

				console.log(pattern.test(str)); // false
	3.数量词
		exp{3}   	将前面表达式匹配3次
		exp{3,5}   	将前面表达式匹配3~5次
		exp{3,}   	将前面表达式匹配3+次

		exp*		将前面表达式匹配0次或多次	
		exp+ 		将前面表达式匹配1次或多次

		贪婪匹配(默认情况下) 	-->  尽可能多的匹配
			var pattern = /\d{3,}/img;
			var str = 'abc123456789';

			console.log(pattern.exec(str)); // 123456789

		非贪婪匹配  -->  尽可能少的匹配
			var pattern = /\d{3,}?/img;
			//var pattern = /\d{3}/img;
			var str = 'abc123456789';

			console.log(pattern.exec(str)); // 123	
			
6)判断邮箱	
	279923224@qq.com
	xupf123@163.com
	zhangsan@briup.cn

	var pattern = /^(\w)+@(\w)+\.(\w{2,3})/img;
	var str = '[email protected]';

	console.log(pattern.test(str));
	

18.包装器类型

基本包装器
	Number() String () Boolean()
	进行基本数据类型得转换
除此之外
	Math() Date() ...
思考:如何将一个字符串转换为数组?
	'hello' -> ['h','e','l','l','o']
	方法一:for循环
		var str  = 'hello';
		var result = [];
		
		for(var i=0;i<str.length;i++){
		    result.push(str[i]);
		}
		console.log(result);// [ 'h', 'e', 'l', 'l', 'o' ]
	方法二:使用String()包装器的方法split()
		var str = 'hello';
		var result = str.split('');
		
		console.log(result);// [ 'h', 'e', 'l', 'l', 'o' ]

String.prototype.xxx
	length
			获取字符串的长度(数量)
			var str  = 'hello';
			console.log(str.length); // 5
	charAt(index)
			获取指定索引上对应的字符
			var str = 'hello';
			console.log(str.charAt(4)); //'o'	获取索引为4的字符
	charCodeAt(index)
			获取指定索引处的字符编码
			var str = 'helloworld';
			console.log(str.charCodeAt(4)); // 111

	indexOf(val)
		获取指定字符在字符串中首次出现时的索引,如果该字符不属于字符串,返回-1
		var str = 'helloworld';
		var result = str.indexOf('l');

		console.log(result); // 2  获取'l'在字符串中首次出现时的索引


		var str = 'helloworld';
		var result = str.indexOf('1');

		console.log(result); // -1  也就是说数字1不属于该字符串

		拓展:数组去重  -->  数组中也有indexOf()方法,可以返回数组中某个指定的元素首次出现时的索引
			var arr = [1,2,3,1,2,5]
			-->
			var arr = [1,2,3,5]


			分析:
				var arr = [1,2,3,1,2,5]
					数组的索引0 1 2 3 4 5
					检测结果  0 1 2 0 1 5

			初步结果:arr.indexOf(arr[i]) != i时,将该元素删除

			解决方案:
				var arr = [1,2,3,1,2,5];

				function norepeat(arr){
				    for(var i=0;i<arr.length;i++){
				        if(arr.indexOf(arr[i]) != i){
				            arr.splice(i,1);
				            i--;
				        }
				    }
				    return arr;
				}

				var result = norepeat(arr);
				console.log(result);

			执行过程:
				arr.indexOf(arr[i]) 		i
						0			        0
						1					1
						2					2
						0					3

	concat()	
		连接两个字符串
		var str1 = 'hello';
		var str2 = 'world';
		console.log(str1.concat(str2)); // 'helloworld'

	slice(begin,end)
		截取子字符串,begin为开始位置,end为结束位置,截取时,不包含结束位置
		var str = 'helloworld';
		console.log(str.slice(2,4)); // 'll'

	trim()
		删除字符串左右两侧的空格,无法删除字符串中间的空格
		var str = ' hello world ';
		console.log(str.trim()); // 'hello world';

	toUpperCase()
		转换为大写
		var str = 'hello world';
		console.log(str.toUpperCase()); // 'HELLO WORLD'

	toLowerCase()
		转换为小写
		var str = 'HELLO WORLD';
		console.log(str.toLowerCase()); // 'hello world'

	match(regexp)
		查找匹配的内容,返回一个数组,保存的是所有匹配的内容
		var str = 'hello';
		var pattern = /he/img;

		console.log(str.match(pattern)); // ['he']

	split()
		把字符串分割为字符串数组
		使用了''
			var str = 'hello';
			var result = str.split('');
			console.log(result); // [ 'h', 'e', 'l', 'l', 'o' ]
		没有使用''
			var str = 'hello';
			var result = str.split();
			console.log(result); // [ 'hello' ]

			等价于
			var str = 'hello';
			var arr = [];
			arr.push(str);

			console.log(arr); // [ 'hello' ]


	

19.Math对象

	Math.ceil()		向上舍入
	Math.floor()	向下舍入
	Math.round()	四舍五入
	Math.random() 	会产生一个随机数,0-1之间的小数

	var num = 12.6;

	console.log(Math.ceil(num)); // 13
	console.log(Math.floor(num)); // 12
	console.log(Math.round(num)); // 13
	

20.Date日期对象

1) 实例化日期对象
		var date = new Date();
		console.log(date); // 2020-04-27T06:06:51.271Z

		此时间表示世界标准时间,我们中国属于东八区,需要加8小时才是我们的时间

2) Date对象的方法
	getDate()
		返回一个月中的某一天(0-31)
		var date = new Date();
		var result = date.getDate();

		console.log(result); // 27

	getFullYear()
		返回一个表示年份的4位数字
		var date = new Date();
		var result = date.getFullYear();

		console.log(result); // 2020

	getMonth()
		返回表示月份的数字(0-11)0表示一月,11表示12var date = new Date();
		var result = date.getMonth();

		console.log(result); // 3

	getDay()
		返回一个星期中的某一天 (0-6)0表示周日,6表示周六
		var date = new Date();
		var result = date.getDay();

		console.log(result); // 1

	getHours()
		返回时
	getMinutes()
		返回分
	getSeconds()
		返回秒
			var date = new Date();
			var hour = date.getHours();
			var minute = date.getMinutes();
			var second = date.getSeconds();

			console.log(date);
			console.log(hour);
			console.log(minute);
			console.log(second);

	getTime()
		返回一个时间戳,从197011日至今的毫秒数

		时间戳	
			格林威治时间197011000000秒
			至
			现在的总秒数
		var date = new Date();
		var timeAll = date.getTime();

		console.log(date);
		console.log(timeAll);

	toLocaleString()
		根据本地时间把Date对象转换为字符串,并返回
		2020/04/27 14:34:23

		var date = new Date();
		console.log(date.toLocaleString()); // 4/27/2020, 2:34:23 PM
		
3) 前后端交互
		前台		-> 		后台
			时间戳
		后台		-> 		前台
			时间戳

			2020/04/27 14:38:10

		思考:
			1. 如何将标准时间转换为正常的时间格式? 2020-04-27 14:57:20
			方法一:(原生js)
				var date = new Date();
				function timeFormat(dateStr){
				    //获取年份
				    var year = dateStr.getFullYear();
				    //获取月份
				    var month = (dateStr.getMonth() + 1).toString();
				    //获取日
				    var day = dateStr.getDate().toString();
				    //获取小时
				    var hour = dateStr.getHours().toString();
				    //获取分钟
				    var minute = dateStr.getMinutes().toString();
				    //获取秒
				    var second = dateStr.getSeconds().toString();
				    return year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second;
				}
				var result = timeFormat(date);

				console.log(date);
				console.log(result,'---');


				补全位数:padStart(2,'0')
				var date = new Date();
				function timeFormat(dateStr){
				    var dt = dateStr;
				    //获取年份
				    var year = dt.getFullYear();
				    //获取月份
				    var month = (dt.getMonth() + 1).toString().padStart(2,'0');
				    //获取日
				    var day = dt.getDate().toString().padStart(2,'0');
				    //获取小时
				    var hour = dt.getHours().toString().padStart(2,'0');
				    //获取分钟
				    var minute = dt.getMinutes().toString().padStart(2,'0');
				    //获取秒
				    var second = dt.getSeconds().toString().padStart(2,'0');

				    return year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second;
				}
				var result = timeFormat(date);

				console.log(date);
				console.log(result,'---');

			方法二:(第三方库moment.js)
				var date = new Date();
				var result = moment(date).format('YYYY/MM/DD hh:mm:ss');
				console.log(result);

			2.如何将时间戳转换为正常时间格式?
				var date = new Date();
				//获取时间戳
				var timeAll = date.getTime();
				//使用moment处理时间格式
				var result = moment(timeAll).format('YYYY/MM/DD hh:mm:ss');
				console.log(result);

			前端中第三方库的使用
				.html	 script标签引入 cdn
				vue		 通过npm下载
			cdn	
				https://www.bootcdn.cn/all/

			第三方库
				moment
				lodash
				qs

21.高级面向对象

目的:利用一种机制帮我们创建具有特殊功能的对象
1)封装/创建对象的过程【api的本质】
	1.工厂对象模型
		提供了一个函数,每调用一次这个函数,返回一个对象
		function factory(name,age,gender){
		   var obj = {
		        name:name,
		        age:age,
		        gender:gender,
		        sayMessage:function(){
		            console.log(this.name,this.age,this.gender)
		        }
		    }
		    return obj;
		}

		var obj1 = factory('xpf',25,'male');
		var obj2 = factory('zhangsan',30,'male');

		console.log('obj1',obj1);//obj1 { name: 'xpf',age: 25,gender: 'male',sayMessage: [Function: sayMessage] }
		console.log('obj2',obj2);//obj2 { name: 'zhangsan',age: 30,gender: 'male',sayMessage: [Function: sayMessage] }

		obj1.sayMessage(); // xpf 25 male
		obj2.sayMessage(); // zhangsan 30 male

		需求:上面的代码创建的两个对象都是'人',现在希望创建两个对象,一个是'人',另一个是'狗'
			function factory(name,age,gender){
			    return {
			        name:name,
			        age:age,
			        gender:gender,
			        sayMessage:function(){
			            console.log(this.name,this.age,this.gender)
			        }
			    }
			}

			var obj1 = factory('xpf',25,'male');
			var obj2 = factory('小黑',3,'雄性');

			console.log('obj1',obj1);
			console.log('obj2',obj2);

			console.log(typeof(obj1)); // object
			console.log(typeof(obj2)); // object

		解决:
			创建多个相似对象时,代买冗余的问题
		问题:
			1、类型无法细分(由于使用了return {},所以创建出来的所有obj实例都是Object类型)
			2、函数会重复的创建/破坏了封装性
				创建多个对象的时候,需要多次的调用factory函数,即每调用一次该函数,都会内存中开辟一块属于sayMessage的空间

2. 构造函数模式(手机)
	系统内置构造函数(自带的app)
		Object、Array、Date、Math、Number、String、RegExp
		new Object()
		new Array()

	自定义构造函数(下载的app)
		1) js中可以自定义构造函数,从而自定义对象的属性与方法
		2) 构造函数的首字母大写

		function Person(){}

		//人的构造函数
		function Person(name,age,gender){
		    this.name = name;
		    this.age = age;
		    this.gender = gender;
		    this.words = function(){
		        console.log('咕咕咕');
		    }
		}
		//per1叫做实例
		var per1 = new Person('xpf',25,'male');
		var per2 = new Person('zhangsan',25,'male');
		console.log('per1',per1);
		per1.words(); // 咕咕咕
		per2.words(); // 咕咕咕

		//狗的构造函数
		function Dog(name,age,gender){
		    this.name = name;
		    this.age = age;
		    this.gender = gender;
		}
		var dog1 = new Dog('小黑',3,'雄性');
		console.log('dog1',dog1);

		--->

		function Dog(name,age,gender){
			var obj = {}
		    obj.name = name;
		    obj.age = age;
		    obj.gender = gender;
		}

	现象:
		1、构造函数的首字母大写 --> 规范
		2、没有显式的创建对象
		3、将属性和方法赋值给了this对象
		4、没有return语句

	本质:使用new关键字调用构造函数创建对象,实际上执行了如下步骤
		隐式
		1、创建一个对象
		2、将构造函数的作用域赋值给了这个对象(this指向该对象)
		3、执行构造函数中的代码(新增属性和方法)
		4、返回一个对象

	区别:构造函数与普通函数的区别
		1、构造函数也是一个普通函数,创建方式与普通函数一样(函数声明),但是构造函数的首字母大写
			function Person(){}
			function people(){}
		2、调用方式不一样
			普通函数的调用方式:直接调用 people()
			构造函数的调用方式:使用new关键字调用 new Person()
		3、返回值不一样
			普通函数:因为没有返回值,结果为undefined
				function people(){

				}
				var peo = people();
				console.log(peo); // undefined
			构造函数:会立马创建一个对象,所以说返回值为空对象
				function Person(){

				}
				var per = new Person();
				console.log(per); // Person {}
	解决:	
		解决了类型无法细分的问题
	问题:
		函数会重复的创建/破坏了封装性
		每个words方法都要在每个实例上重新创建一次,也就是说每次调用构造函数的时候,都会创建一个对象,而对象中又会每次的去创建一个words方法(函数)

3. 构造函数与原型结合的模式(真正解决方案)
	属性保存在实例中,方法保存在构造函数的原型中
	function Person(name,age,gender){
	    this.name = name;
	    this.age = age;
	    this.gender = gender;
	}
	Person.prototype.words = function(){
	    console.log('哈哈哈');
	}

	var per1 = new Person('xpf',25,'male');
	var per2 = new Person('zhangsan',30,'male');
	console.log('per1',per1);
	console.log('per2',per2);
	per1.words();
	per2.words();
	console.log(per1.words === per2.words); // true

	per1和per2都可以调用构造函数原型中方法words

2) 继承
当我们创建一个构造函数的时候,构造函数会获得一个prototype属性,该属性是一个指针,它会指向一原型对象,原型对象中也包含一个属性constructor,该属性也是一个指针,指向构造函数,当我们使用该构造函数创建实例的时候,该实例也会获得一个属性[[Prototype]],该属性会指向原型对象
function Person(){}

1. 原型链继承 (子构造函数的原型指向父构造函数的实例)
	原理:让一个引用类型继承另一个引用类型的属性和方法
	核心代码:
		Person2.prototype = new Person1();
		Person2.prototype.constructor = Person2;
	
	function Person1(name,age,gender){
	    this.name = name;
	    this.age = age;
	    this.gender = gender;
	}
	Person1.prototype.money = function(){
	    console.log('哈哈哈,我很有钱!');
	}
	var per1 = new Person1('zhangsan',12,'male');
	var per2 = new Person1('lisi',10,'female');
	console.log(per1);
	console.log(per2);
	per1.money();
	per2.money();

	Person2.prototype = new Person1();
	Person2.prototype.constructor = Person2;

	function Person2(name,age,gender){
	    this.name = name;
	    this.age = age;
	    this.gender = gender;
	}

	var per3 = new Person2('xiaohong',10,'female');
	var per4 = new Person2('xiaoming',8,'male');
	console.log('per3',per3);
	console.log('per4',per4);
	per3.money();

2. 借用构造函数(不仅方法可以继承,属性也可以继承)	
	核心代码:
		Person1.call(this,name,age,gender)

	function Person1(name,age,gender){
	    this.name = name;
	    this.age = age;
	    this.gender = gender;
	}
	Person1.prototype.money = function(){
	    console.log('哈哈哈,我很有钱!');
	}
	var per1 = new Person1('zhangsan',12,'male');
	var per2 = new Person1('lisi',10,'female');
	console.log(per1);
	console.log(per2);
	per1.money();
	per2.money();

	Person2.prototype = new Person1();
	Person2.prototype.constructor = Person2;

	function Person2(name,age,gender){
		//借用构造函数
	    Person1.call(this,name,age,gender);
	}

	var per3 = new Person2('xiaohong',10,'female');
	var per4 = new Person2('xiaoming',8,'male');
	console.log('per3',per3);
	console.log('per4',per4);
	per3.money();
	

22.DOM(文档对象模型)

1.作用
	js操作html
	选中浏览器页面任意元素
		var dom = document.getElementById('#app')
		var dom = document.getElementsByTagName('test')
	绑定事件
		dom.onclick = function(){}
	监听	
		dom.addEventListener(function(){})

2.DOM构造函数树
	<div>hello</div>

	Node(节点)
		文档节点	Document类型 
		元素节点	Element类型 		<div></div>
		文本节点	Text类型			hello
		注释节点	Comment类型		<!--注释-->

3.实例化(如何创建一个对象)
	var dom = document.getElementById('one');

4.API(火狐mdn)
	Document
		表示整个html文档,一般情况下一个html可以使用一个Document的实例来表示,即document
		Document类型 --> document
			属性
				title
				head
				body
			方法
				通过id 			getELementById()
				通过classgetELementsByClassName()[0]
				通过name属性		getELementsByName()[0]
				通过标签名		getELementsByTagName()[0]
5.Element(元素节点)					
		标签
			div、p、span、img...
		属性
			id
			name
			href
			src
			alt
			target
			style
				获取元素的样式
			innerHTML
				获取或设置一个元素内的html内容,包括换行
			innerText
				获取或设置一个元素内的文本内容
		方法
			getAttribute(属性名)
				返回指定的属性值

				dom.getAttribute('style')
				返回style的属性值

			setAttribute(属性名,属性值)
				把指定的属性设置或者修改为指定的值,注意该方法没有返回值

				dom.setAttribute('class','xpf')class的值修改为xpf

			querySelector(选择器)
				返回文档中匹配指定css选择器的第一个元素
			querySelectorAll(选择器)
				返回文档中匹配指定css选择器的所有元素
6.Text
7.Comment
8.节点的操作
		1) 节点的创建
			document.createElement('标签名')

			document.createElement('div')表示创建一个div标签

		2)节点的追加
			1. appendChild(newDom);

			在parent的最后放追加一个新节点,newDom可以是新创建的节点,也可以是原本已存在的节点
			注意:
				任何DOM节点不能同时出现在文档中多个位置
				==>
				如果追加的节点原本已存在,只会改变该节点的位置

			2. insertBeofre(newDom,item1)
				第一个参数为要插入的节点
				第二个参数为要插入的位置

		3) 节点的删除
			removeChild('节点')

			parent.removeChild(item3);
			将父元素parent的孩子item3删除

		4) 节点的复制(克隆)
			1. 浅复制
				cloneNode() / cloneNode(false)
				默认为浅复制,只复制标签,内容不复制

			2. 深复制
				cloneNode(true)
				传递一个参数true,复制的是标签及内容
9.事件
		1) 事件的三要素
			1. 事件目标
				获取事件源
			2. 事件处理函数
				为事件源绑定事件处理函数,当绑定的事件类型被触发的时候执行该函数
			3. 事件对象
				当事件处理函数执行的时候,dom会将事件对象作为参数传递给事件处理函数

				一般用event表示

		2) 事件流
			描述的是从页面中接收事件的顺序

			1. 事件冒泡
				含义:
					事件开始由最具体的元素接收,然后逐级向上传播到不具体的节点
				特点:
					从内往外
				前提:
					1、 元素需要嵌套
					2、 每层元素上都要绑定事件

				<div class="outer">
					<div class="center">
						<div class="inner"></div>
					</div>
				</div>

				阻止事件冒泡
					event.stopPropagation()
				当前点击的事件对象
					event.target

			2. 事件捕获
				含义:
					不具体的DOM节点应该更早的接收事件,而具体的节点最后接收到事件
				特点:
					由外往内
				前提:
					1、 元素需要嵌套
					2、 每层元素上都要绑定事件
				参数:
					第一个参数是	事件类型(click、mouseover...)
					第二个参数是	事件处理函数
					第三个参数是	布尔值,用于描述事件是冒泡还是捕获,该参数可选
						true  --> 事件捕获
						false --> 事件冒泡
				语法:
					outer.addEventListener('click',function(){
						console.log(this)
					},true)

		3) 事件绑定方式
			1. onxxx
				onclick、onmouseover...
				属性,简单,兼容性好

				outer.onclick = function(){}

			2. addEventListener
				方法
				outer.addEventListener('click',function(){
					console.log(this)
				},true)
				对浏览器版本有要求

			3. attachEvent
				方法
				IE低版本下才能兼容

		4) 事件类型
			click 	鼠标点击

			scroll 	页面滚动

			keyup	键盘抬起
			keydown	键盘落下

			focus	聚焦
			blur	失焦

			mouseover	光标移动到元素上,支持子元素
			mouseout	光标移出元素,支持子元素

			mouseenter	光标移动到元素上,不支持子元素
			mouseleave	光标移出元素,不支持子元素

			onload	
				window.onload 当前页面内容加载完毕
		5) 事件代理
			用法:	
				将事件绑定在当前元素的父元素上而非当前元素,这时候,当点击当前元素的时候,执行父元素上绑定的事件处理函数
			好处:
				父元素代理子元素所有的事件,子元素可以动态的添加和删除而不用频繁的绑定事件
				

23.BOM(浏览器对象模型)

使用JavaScript来访问和控制浏览器对象

	1) 超时调用
		含义:
			在指定的毫秒数后调用函数
		语法:
			setTimeout(function(){},time)
		参数:
			第一个参数是 		要执行的代码
			第二个参数是 		以毫秒表示的时间
				1000毫秒 = 1秒
		返回值:
			返回一个ID(数字),可以将这个ID传递给clearTimeout()来取消执行
			var id = setTimeout(function(){},time)
		清除:
			clearTimeout(id)
	
	2) 间歇调用
		含义:
			按照指定的周期(以毫秒计数)来调用函数,该方法会不停的被调用,直到该窗口被关闭或clearInterval被调用
		语法:
			setInterval(function(){},time)
		参数:
			第一个参数是 		要执行的代码
			第二个参数是 		以毫秒表示的时间
				1000毫秒 = 1秒
		返回值:
			返回一个ID(数字),可以将这个ID传递给clearInterval()来取消执行
			var id = setInterval(function(){},time)
		清除:
			clearInterval(id)
	
		案例一:点名
		案例二:根据栏目名查询信息
	
	3) 系统对话框
		alert()	
			警告框,会阻塞代码的运行,该方法接受一个字符串,显示给用户
		confirm()
			确认对话框
	
	4) Location对象
		包含有关当前URL的信息
		1. 属性
			host
				返回一个URL的主机名和端口
			href
				返回完整的URL
			port
				返回一个端口号
		2. 方法
			assign(url)
				会载入一个新的url,并在浏览记录中生成一个新的记录(可以回退)
			replace(url)
				会载入一个新的url,不会在浏览记录中生成一个新的记录(不可以回退)
			reload()
				重新加载当前页面(刷新)
	
	*5) 存储对象
		浏览器提供了sessionStorage(会话存储)和localStorage(本地存储)来对网页的数据进行添加、删除、查询操作
	
		localStorage
			用于长久的保存整个网站的数据,保存的数据没有过期时间,除非手动去除
		sessionStorage
			临时保存同一窗口的数据,在窗口关闭或浏览器关闭的时候会删除这些数据
	
		方法:(键值对)
			getItem(key)
				返回指定键的值
			setItem(key,value)
				添加键和值
			removeItem(key)
				删除指定键
			clear()
				清除所有的键

你可能感兴趣的:(html5 css3 JavaScript 语法)