JS学习笔记

1. CSS 

1.1 文档流

- 所有的元素默认情况下都是在文档流中存在的
- 文档流是网页的最底层
- 元素在文档流中的特点:
    - 块元素
        1.默认宽度是父元素的全部
        2.默认高度被内容(子元素)撑开
        3.在页面中自上而下垂直排列
    - 内联元素
        1.默认高度和宽度都被内容撑开
        2.在页面中自左向右水平排列,如果一行不足以容下所有的元素
            则换到下一行继续从左向右

1.2 浮动

使用float来设置元素的浮动

- 可选值:
    none 默认值,元素不浮动,就在文档流中
    left 元素向页面的左侧浮动
    right 元素向页面的右侧浮动
- 浮动特点:
    1.元素设置浮动以后,会完全脱离文档流,并向页面的左上或右上浮动。
            直到遇到父元素的边框或其他的父元素时则停止浮动。
    2.如果浮动元素上边是一个没有浮动的块元素,元素不会超过该块元素。
    3.浮动元素的浮动位置不能超过他上边浮动的兄弟元素,最多一边齐
    4.浮动元素不会覆盖文字,文字会围绕在浮动元素的周围,所以可以通过浮动来实现文字环绕图片的效果。
    
- 浮动以后元素会完全脱离文档流,脱离文档流以后元素会具有如下特点:
    1.块元素不独占一行
    2.块元素的宽度和高度都被内容撑开
    3.元素不在文档流占用位置
    4.内联元素会变成块元素
    
- 高度塌陷
    - 在文档流中元素的高度默认被子元素撑开,当子元素浮动时,子元素会脱离文档流,
        此时将不能撑起父元素的高度,会导致父元素的高度塌陷。父元素高度塌陷会导致其他元素的位置上移,导致页面的布局混乱。
    - 可以通过开启元素的BFC来处理高度塌陷的问题。
        - BFC叫做Block Formatting Context
        - 它是一个隐含属性,默认情况是关闭,当开启以后元素会具有如下的特性:
            1.父元素的垂直外边距不会和子元素重叠
            2.开启BFC的元素不会被浮动元素覆盖
            3.父元素可以包含浮动的子元素
        - 开启BFC的方式很多:
            1.设置元素浮动
            2.设置元素绝对定位
            3.设置元素为inline-block
            4.将元素的overflow设置为一个非默认值
        - 一般我们采取副作用比较小的方式
            overflow:hidden;

1.3 定位

通过定位可以将元素摆放到页面的任意位置

- 使用position来设置元素的定位
    - 可选值:
        - static 默认值 元素不开启定位
        - relative 开启元素的相对定位
        - absolute 开启元素的绝对定位
        - fixed 开启元素的固定定位
        
    - 相对定位
        1.相对于元素自身在文档流中的位置进行定位
        2.相对定位的元素不会脱离文档流,定位元素的性质不会改变,块还是块,内联还是内联
        3.如果不设置偏移量,元素不会发生任何的变化
        4.会提升元素的层级
        
    - 绝对定位
        1.相对于离它最近的开启了定位的祖先元素进行定位,如果祖先元素都没有开启定位则相对于浏览器窗口进行定位。
        2.绝对定位会使元素完全脱离文档流,会改变元素的性质,内联变成块元素,块元素的宽度被内容撑开
        3.绝对定位的元素如果不设置偏移量,元素的位置不会发生变化
        4.会提升元素的层级
        
    - 固定定位
        - 固定定位也是一种绝对定位,它的大部分特点都和绝对定位是相同的。
        - 不同的是:
            - 固定定位永远相对于浏览器窗口进行定位
            - 固定定位会固定在浏览器的指定的位置,不会随页面一起滚动
            
    - 偏移量
        - 当元素开启了定位以后,可以通过四个偏移量来设置元素的位置
            top:相对于定位位置的顶部的偏移量
            bottom:相对于定位位置的底部的偏移量
            left:相对于定位位置的左侧的偏移量
            right:相对于定位位置的右侧的偏移量
            
        - 一般只需要使用两个值即可给元素进行定位
            top left
            top right
            bottom left
            bottom right
            
        - 偏移量也可以指定一个负值,如果是负值则元素会向相反的方向移动
        
    - 层级
        - 当元素开启定位以后,可以通过z-index来设置层级,
            它需要一个正整数作为参数,值越大层级越高,层级越高越优先显示
            如果层级一样,则后边的会盖住前边的,父元素永远都不会盖住子元素。
            
        - 文档流 < 浮动 < 定位    
        
    - 元素的透明
        使用opacity来设置元素的透明度
            - 需要一个0-1之间的值
            - 0 表示完全透明
            - 1 表示完全不透明
            
        IE8及以下的浏览器不支持该样式,需要使用如下方式来设置
            filter:alpha(opacity=透明度);
            - 需要一个0-100之间的值
            - 0 表示完全透明
            - 100 表示完全不透明

2. HTML 

2.1 表格

在网页中可以通过表格来表示一些格式化的数据。

- 表格相关的标签
    - <table> 用来创建一个表格
    - <tr> 表示表格中的一行
    - <th> 表示表头中的单元格
    - <td> 表示表格中的单元格
        - 属性:
            colspan 横向的合并单元格
            rowspan 纵向的合并单元格
    - 例子:
        <table>
            <tr>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
            </tr>
        </table>
        
    - 长表格
        - <thead> 表格的头部
        - <tbody> 表格的主体
            - 注意:如果表格中没有写thead tbody tfoot,浏览器会自动向table中添加一个tbody
                并且将所有的tr都放到tbody中,tr是tbody的子元素,不是table的子元素
        - <tfoot> 表格的底部

<!--
	在生活中经常会使用表格来表示一些格式化的数据:比如 :课程表 银行对账单  人名单
	同样在网页中也可以使用表格来表示一些格式化的数据
	使用table标签来创建一个表格
-->
<table border="1" width="20%" align="center">
	<!--在table标签中使用tr来表示表格中的一行,有几行就有几个tr-->
	<tr>
		<!--在tr中使用td表示一个单元格,有几个td就有几个单元格-->
		<td>A1</td>
		<td>A2</td>
		<td>A3</td>
		<td>A4</td>
	</tr>
	
	<tr>
		<td>B1</td>
		<td>B2</td>
		<!--使用rowspan来纵向的合并单元格-->
		<td rowspan="2">B4</td>
	</tr>
	
	<tr>
		<td>C1</td>
		<td>C2</td>
		<td>C3</td>
	</tr>
	
	<tr>
		<td>D1</td>
		<td>D2</td>
		<!-- 使用colspan来横向的合并单元格-->
		<td colspan="2">D3</td>
	</tr>
</table>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			table{
				/*设置一个宽度*/
				width: 300px;
				/*设置居中*/
				margin: 50px auto;
				/*设置一个边框*/
				/*border: 1px solid black;*/
				/*border-spacing可以用来设置表格边框之间的距离*/
				border-spacing: 100px;
				
				/*
				 * border-collapse可以用来设置表格的边框的合并
				 * 	如果将值设置collapse,则table和td的边框将会自动合并为一个
				 * 	当设置了边框合并以后,border-spacing将自动失效
				 */
				border-collapse: collapse;
			}
			
			td,th{
				/*设置边框*/
				border: 1px solid black;
			}
			
			tbody > tr{
				background-color: #bfa;
			}
			
			
		</style>
	</head>
	<body>
		
		<!-- table是一个块元素 -->
		<table>
			<!--
				我们在创建一个表格时,如果没有使用thead tbody tfoot这些标签时,
					浏览器会自动在页面中添加tbody,并且将所有的tr都放到tbody中
					所以实际上tr并不是table子元素,而是tbody的子元素
			-->
			<tr>
				<!--在html中还为我们提供了一个th标签,专门用来表示表头的单元格-->
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>住址</th>
			</tr>
			<tr>
				<td>1</td>
				<td>孙悟空</td>
				<td>18</td>
				<td>花果山</td>
			</tr>
			<tr>
				<td>2</td>
				<td>猪八戒</td>
				<td>28</td>
				<td>高老庄</td>
			</tr>
			<tr>
				<td>3</td>
				<td>沙和尚</td>
				<td>38</td>
				<td>流沙河</td>
			</tr>
		</table>
		
	</body>
</html>
<table>
	<!-- 
		HTML中还为我们提供了三个标签,用来将表格分成三个部分
		<thead>
		<tbody>
		<tfoot>
			
		我们可以将对应部分的tr,放到指定的标签	
		使用这三个标签创建的表格,在打印时,会在每页都打印表格的头部和底部
			无论编写到什么位置,thead中的内容,永远都会显示在表格的头部
				而tfoot中的内容,永远都会显示在表格的底部
	-->
	
	<!--表格的头部-->
	<thead>
		<tr>
			<td>日期</td>
			<td>收入</td>
			<td>支出</td>
			<td>合计</td>
		</tr>
	</thead>
	<!--表格的底部-->
	<tfoot>
		<tr>
			<td></td>
			<td></td>
			<td>合计</td>
			<td>300</td>
		</tr>
	</tfoot>
	
	<!--表格的主要内容-->
	<tbody>
		<tr>
			<td>16.11.11</td>
			<td>500</td>
			<td>300</td>
			<td>200</td>
		</tr>
		<tr>
			<td>16.11.11</td>
			<td>500</td>
			<td>300</td>
			<td>200</td>
		</tr>
		<tr>
			<td>16.11.11</td>
			<td>500</td>
			<td>300</td>
			<td>200</td>
		</tr>
	</tbody>
</table>
<!--
	在一个表格中也可以嵌套其他的表格
		在很久以前,我们经常使用表格在页面中进行布局,此时就需要使用大量的表格的嵌套
		表格布局,布局起来非常的简单,但是维护起来非常的麻烦,所以现在已经很少有人用
	表格的列数由td最多的那个tr来决定
-->
<table border="1" width="100%">
	<tr>
		<td height="120" colspan="2"></td>
	</tr>
	<tr>
		<td height="400" width="20%"></td>
		<td height="400">
			<table border="1" width="100%" height="100%">
				<tr>
					<td></td>
				</tr>
				<tr>
					<td></td>
				</tr>
			</table>
		</td>
	</tr>
	<tr>
		<td height="120" colspan="2"></td>
	</tr>
</table>

2.2 表单

表单可以将用户的信息提交到服务器中。

- <form>
    - 用来创建一个表单

    - 属性:
        action:需要一个服务器地址,提交表单时表单中的内容将会被提交到该地址
- 表单项
    - <input />
        - 它可以根据不同的type属性值,生成不同的表单项
        - type="text" 文本框 <input type="text" name="" />
        - type="password" 密码框 <input type="password" name="" />
        - type="radio" 单选按钮 <input type="radio" name="" value="" checked="checked" />
        - type="checkbox" 多选框 <input type="checkbox" name="" value="" checked="checked" />
        - type="submit"  提交按钮 <input type="submit" value="按钮上的文字" />
        - type="reset"  重置按钮 <input type="reset" value="按钮上的文字" />
        - type="button" 普通按钮 <input type="button" value="按钮上的文字" /> 

        
    - <select>
        - 下拉列表
        - <select name="">
                <option value="" selected="selected"></option>
                <option value=""> </option>
                <option value=""></option>
            </select>
    
    - <button>
        - 按钮功能input那几个按钮一样,但是它们要灵活一些
            <button type="submit">按钮的文字</button>
            <button type="reset">按钮的文字</button>
            <button type="button">按钮的文字</button>

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<!-- 使用form标签来创建一个表单,form中有一个必须的属性叫做action,
			action需要一个服务器的地址,当我们提交表单时,填写的内容将会提交到action指向的地址 -->

		<form action="target.html">
			<!-- 在form中可以创建一个表单项,用户可以通过表单项来填写信息 -->
			<!--  文本框
				  使用input标签来创建一个文本框,它需要一个type属性是text
				- 如果希望表单中的内容最终发送到服务器,还必须要给表单项添加一个name属性
					该属性将会作为用户填写内容名字,在服务器中可以根据这个名字来获取用户填写内容
					
				- 默认情况下,用户添加的内容将会以查询字符串的形式发送给服务器,
					所谓的查询字符串就是url地址?后边的内容
				- username=sunwukong&password=123123
				- 查询字符实际上就是一个一个的名值对结构,多个名值对之间使用&隔开
					一个名字 = 一个值
					名字就是表单项指定的name属性值
					值就是用户填写的内容,在服务器中可以通过名字来获取用户填写的内容
					
					可以通过value属性为文本框指定一个默认值!! -->
			用户名 <input type="text" name="username" value="hello" /> <br /><br />
			
			<!-- 密码框也是input,不同的是它type需要使用password -->
			密码 <input type="password" name="password" /> <br /><br />
			
			<!--
				单选按钮
				 - 使用input来创建一个单选按钮,它的type属性值是radio
				 - 单选按钮是通过name属性来分组的,相同的name属性值属于一组!
				 - 像这种选择框不需要用户填写内容的,还必须指定一个value属性,
				 	这样选中的元素的value属性值将会被提交到服务器
				 - 如果希望某个单选按钮处在默认选中的状态可以在标签中添加属性 checked="checked"  -->
			性别 <input type="radio" name="gender" value="male" />男  
				<input type="radio" name="gender" value="female" checked="checked" />女
			<br /><br />
			
			<!-- 多选框
				- 使用input来创建一个多选框
				- 它的type属性是checkbox -->
			爱好 <input type="checkbox" name="hobby" value="ppq" />乒乓球
				<input type="checkbox" name="hobby" value="ymq" checked="checked" />羽毛球
				<input type="checkbox" name="hobby" value="lq" />篮球
				
				<br /><br />
				
			<!-- 下拉列表
				- 使用select来创建一个下拉列表
				- 使用option标签来创建下拉列表中的选项
				- 下拉列表的name属性需要指定给select标签,value属性需要指定给option
				- 如果希望将option设置为默认选中,则可以在option中添加一个属性 selected = "selected"  -->
			你最喜欢的明星
						<select name="star">
							<option value="fbb">范冰冰</option>
							<option value="zw" >赵薇</option>
							<option value="lxr" selected="selected">林心如</option>
						</select>
			
			<br /><br />
			
			<!--  提交按钮
					- 使用input来创建一个提交按钮
					- 它的type叫做submit
					- 通过value属性可以设置提交按钮上的文字
			-->
			<input type="submit" value="注册" />
			
			<!--
				重置按钮
					重置按钮可以使表单恢复到默认值
			-->
			<input type="reset" />
			
			<!--
				如果type设置为button,那么会生成一个普通的按钮,
				它只有一个功能就是被点
			-->
			<input type="button" value="按钮" />
			
			<br /><br />
			
			<!--
				也可以通过button标签来创建按钮
					使用button创建的按钮和input创建的按钮功能一致,
					只不过button标签更加的灵活
			-->
			<button type="submit">提交按钮</button>
			<button type="reset">重置</button>
			<button type="button">单纯的按钮</button>
			
		</form>
	</body>
</html>

3. JS

3.1 JS 基础

JavaScript 负责页面中的的行为。它是一门运行在浏览器端的脚本语言。

1)JS 的编写的位置

① 可以编写到标签的指定属性中

			<button onclick="alert('hello');">我是按钮</button>
			<a href="javascript:alert('aaa');">超链接</a>

② 可以编写到script标签中

			<script type="text/javascript">
				//编写js代码
			</script>

③ 可以将代码编写到外部的js文件中,然后通过标签将其引入

			<script type="text/javascript" src="文件路径"></script>
​
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		
		<!--
			1. 可以将js代码编写到外部js文件中,然后通过script标签引入
			写到外部文件中可以在不同的页面中同时引用,也可以利用到浏览器的缓存机制
			推荐使用的方式
		-->
		<script type="text/javascript" src="js/script.js"></script>
		<!--
			script标签一旦用于引入外部文件了,就不能在编写代码了,即使编写了浏览器也会忽略
			如果需要则可以在创建一个新的script标签用于编写内部代码
		-->
		<script type="text/javascript">
			alert("我是内部的JS代码");
		</script>
		
		<!--
			2. 可以将js代码编写到script标签	
		<script type="text/javascript">
			alert("我是script标签中的代码!!");
		</script>
		-->
	</head>
	<body>
		
		<!--
			3. 可以将js代码编写到标签的onclick属性中
			当我们点击按钮时,js代码才会执行
			
			虽然可以写在标签的属性中,但是他们属于结构与行为耦合,不方便维护,不推荐使用
		-->
		<button onclick="alert('讨厌,你点我干嘛~~');">点我一下</button>
		
		<!--
			4. 可以将js代码写在超链接的href属性中,这样当点击超链接时,会执行js代码
		-->
		<a href="javascript:alert('让你点你就点!!');">你也点我一下</a>
		<a href="javascript:;">你也点我一下</a>
		
	</body>
</html>

​

2)输出语句

① alert("要输出的内容");  //该语句会在浏览器窗口中弹出一个警告框

② document.write("要输出的内容"); //该内容将会被写到body标签中,并在页面中显示

③ console.log("要输出的内容"); //该内容会被写到开发者工具的控制台中

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<!--JS代码需要编写到script标签中-->
		<script type="text/javascript">
			
			/*
			 * 控制浏览器弹出一个警告框
			 */
			alert("哥,你真帅啊!!");
			
			/*
			 * 让计算机在页面中输出一个内容 
			 * document.write()可以向body中输出一个内容
			 */
			document.write("看我出不出来~~~");
			
			/*
			 * 向控制台输出一个内容
			 * console.log()的作用是向控制台输出一个内容
			 */
			console.log("你猜我在哪出来呢?");
		</script>
	</head>
	<body>
	</body>
</html>

3)基础语法

		<script type="text/javascript">
			
			/*
			 	多行注释
			 	JS注释
			 	多行注释,注释中的内容不会被执行,但是可以在源代码中查看
			 		要养成良好的编写注释的习惯,也可以通过注释来对代码进行一些简单的调试
			 */
			
			//单行注释
			//alert("hello");
			//document.write("hello");
			console.log("hello"); //该语句用来在控制台输出一个日志
			
			/*
			 * 1.JS中严格区分大小写
			 * 2.JS中每一条语句以分号(;)结尾
			 * 		- 如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,
			 * 			而且有些时候,浏览器会加错分号,所以在开发中分号必须写
			 * 3.JS中会忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化
			 * 
			 */
			alert("hello");
		</script>

4)字面量和变量

		<script type="text/javascript">
			
			/*
			 * 字面量,都是一些不可改变的值
			 * 		比如 :1 2 3 4 5 
			 * 		字面量都是可以直接使用,但是我们一般都不会直接使用字面量
			 * 
			 * 变量    变量可以用来保存字面量,而且变量的值是可以任意改变的
			 * 		变量更加方便我们使用,所以在开发中都是通过变量去保存一个字面量,
			 * 		而很少直接使用字面量
			 * 		可以通过变量对字面量进行描述
			 */
			
			//声明变量
			//在js中使用var关键字来声明一个变量
			var a;
			
			//为变量赋值
			a = 123;
			a = 456;
			a = 123124223423424;
			
			//声明和赋值同时进行
			var b = 789;
			var c = 0;
			
			var age = 80;
			
			console.log(age);
			
		</script>

5)标识符

在JS中所有的可以自主命名的内容,都可以认为是一个标识符,是标识符就应该遵守标识符的规范。比如:变量名、函数名、属性名。

规范:

  • 标识符中可以含有字母、数字、_、$
  • 标识符不能以数字开头
  • 标识符不能是JS中的关键字和保留字
  • 标识符一般采用驼峰命名法
		<script type="text/javascript">
			
			/*
			 * 标识符
			 * 	- 在JS中所有的可以由我们自主命名的都可以称为是标识符
			 * 	- 例如:变量名、函数名、属性名都属于标识符
			 * 	- 命名一个标识符时需要遵守如下的规则:
			 * 		1.标识符中可以含有字母、数字、_、$
			 * 		2.标识符不能以数字开头
			 * 		3.标识符不能是JS中的关键字或保留字
			 * 		4.标识符一般都采用驼峰命名法
			 * 			- 首字母小写,每个单词的开头字母大写,其余字母小写
			 * 			helloWorld xxxYyyZzz
			 * 
			 * 	- JS底层保存标识符时实际上是采用的Unicode编码,
			 * 		所以理论上讲,所有的utf-8中含有的内容都可以作为标识符
			 */
			/*var if = 123;
			
			console.log(if);*/
			
			
			//千万不要这么用
			var 锄禾日当午 = 789;
			console.log(锄禾日当午);

		</script>

3.2 数据类型

1)数据类型

JS 中一共分成六种数据类型:

  • String 字符串
  • Number 数值
  • Boolean 布尔值
  • Null 空值
  • Undefined 未定义
  • Object 对象

① 其中基本数据类型有:

        - String 字符串
            - JS中的字符串需要使用引号引起来双引号或单引号都行
            - 在字符串中使用\作为转义字符
                \'  ==> '
                \"  ==> "
                \n  ==> 换行
                \t  ==> 制表符
                \\  ==> \    
                
            - 使用typeof运算符检查字符串时,会返回"string"    

        - Number 数值
            - JS中所有的整数和浮点数都是Number类型
            - 特殊的数字
                Infinity 正无穷
                -Infinity 负无穷
                NaN 非法数字(Not A Number)
            - 其他进制的数字的表示:
                0b 开头表示二进制,但是不是所有的浏览器都支持
                0 开头表示八进制
                0x 开头表示十六进制
                
            - 使用typeof检查一个Number类型的数据时,会返回"number"
                (包括NaN 和 Infinity)

		<script type="text/javascript">
			/*
			 * 在JS中所有的数值都是Number类型,
			 * 	包括整数和浮点数(小数)
			 * 
			 * JS中可以表示的数字的最大值
			 * 	Number.MAX_VALUE
			 * 		1.7976931348623157e+308
			 * 
			 * 	Number.MIN_VALUE 大于0的最小值
			 * 		5e-324
			 * 
			 *  如果使用Number表示的数字超过了最大值,则会返回一个
			 * 		Infinity 表示正无穷
			 * 		-Infinity 表示负无穷
			 * 		使用typeof检查Infinity也会返回number
			 *  NaN 是一个特殊的数字,表示Not A Number
			 * 		使用typeof检查一个NaN也会返回number
			 */
			//数字123
			var a = 123;
			//字符串123
			var b = "123";
			/*
			 	可以使用一个运算符 typeof
			 		来检查一个变量的类型
			 	语法:typeof 变量	
			 	检查字符串时,会返回string
			 	检查数值时,会返回number
			 * */
			//console.log(typeof b);
			
			a = -Number.MAX_VALUE * Number.MAX_VALUE;
			a = "abc" * "bcd";
			a = NaN;
			//console.log(typeof a);
			
			a = Number.MIN_VALUE;
			//console.log(a);
			
			/*
			 * 在JS中整数的运算基本可以保证精确
			 */
			var c = 1865789 + 7654321;
			
			/*
			 * 如果使用JS进行浮点运算,可能得到一个不精确的结果
			 * 	所以千万不要使用JS进行对精确度要求比较高的运算	
			 */
			var c = 0.1 + 0.2;
			console.log(c);
		</script>

        - Boolean 布尔值
            - 布尔值主要用来进行逻辑判断,布尔值只有两个
            - true 逻辑的真
            - false 逻辑的假
            - 使用typeof检查一个布尔值时,会返回"boolean"    

        - Null 空值
            - 空值专门用来表示为空的对象,Null类型的值只有一个:null
            - 使用typeof检查一个Null类型的值时会返回"object"

        - Undefined 未定义
            - 如果声明一个变量但是没有为变量赋值此时变量的值就是undefined
            - 该类型的值只有一个 undefined
            - 使用typeof检查一个Undefined类型的值时,会返回"undefined"

② 引用数据类型:Object 对象

2)类型转换

类型转换就是指将其他的数据类型,转换为String Number 或 Boolean。

① 转换为String

- 方式一(强制类型转换):
    - 调用被转换数据的toString()方法
    - 例子:
        var a = 123;
        a = a.toString();
    - 注意:这个方法不适用于null和undefined
        由于这两个类型的数据中没有方法,所以调用toString()时会报错
        
- 方式二(强制类型转换):

    - 调用String()函数
    - 例子:
        var a = 123;
        a = String(a);
    - 原理:对于Number Boolean String都会调用他们的toString()方法来将其转换为字符串,
        对于null值,直接转换为字符串"null"。对于undefined直接转换为字符串"undefined"
        
- 方式三(隐式的类型转换):

    - 为任意的数据类型 +""
    - 例子:
        var a = true;
        a = a + "";
    - 原理:和String()函数一样    

②  转换为Number

            - 方式一(强制类型转换):
                - 调用Number()函数
                - 例子:
                    var s = "123";
                    s = Number(s);
                - 转换的情况:
                    1.字符串 --> 数字
                        - 如果字符串是一个合法的数字,则直接转换为对应的数字
                        - 如果字符串是一个非法的数字,则转换为NaN
                        - 如果是一个空串或纯空格的字符串,则转换为0
                    2.布尔值 --> 数字
                        - true转换为1
                        - false转换为0
                    3.空值 --> 数字
                        - null转换为0
                    4.未定义 --> 数字
                        - undefined 转换为NaN
                        
            - 方式二(强制类型转换):

                - 调用parseInt()或parseFloat()
                - 这两个函数专门用来将一个字符串转换为数字的
                - parseInt()
                    - 可以将一个字符串中的有效的整数位提取出来,并转换为Number
                    - 例子:
                        var a = "123.456px";
                        a = parseInt(a); //123
                    - 如果需要可以在parseInt()中指定一个第二个参数,来指定进制    
                        
                - parseFloat()
                    - 可以将一个字符串中的有效的小数位提取出来,并转换为Number
                    - 例子:
                        var a = "123.456px";
                        a = parseFloat(a); //123.456
                        
            - 方式三(隐式的类型转换):

                - 使用一元的+来进行隐式的类型转换
                - 例子:
                    var a = "123";
                    a = +a;
                    
                - 原理:和Number()函数一样    

		<script type="text/javascript">
			var a = 123;
			/*
			 * 在js中,如果需要表示16进制的数字,则需要以0x开头
			 * 			如果需要表示8进制的数字,则需要以0开头
			 * 			如果要要表示2进制的数字,则需要以0b开头
			 * 				但是不是所有的浏览器都支持
			 * 	
			 */
			
			//十六进制
			a = 0x10;
			a = 0xff;
			a = 0xCafe;
			
			//八进制数字
			a = 070;
			
			//二进制数字
			//a = 0b10;
			
			//向"070"这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析
			a = "070";
			
			//可以在parseInt()中传递一个第二个参数,来指定数字的进制
			a = parseInt(a,10);
			
			console.log(typeof a);
			console.log(a);

			//对于Number调用toString()时可以在方法中传递一个整数作为参数
			//此时它将会把数字转换为指定的进制,如果不指定则默认转换为10进制
			a = a.toString(2);
			
			console.log(a);
			console.log(typeof a);
		</script>

③ 转换为布尔值

            - 方式一(强制类型转换):
                - 使用Boolean()函数
                - 例子:
                    var s = "false";
                    s = Boolean(s); //true
                - 转换的情况
                    字符串 --> 布尔
                        - 除了空串其余全是true
                        
                    数值 --> 布尔
                        - 除了0和NaN其余的全是true
                        
                    null、undefined ---> 布尔
                        - 都是false
                        
                    对象 ---> 布尔
                        - 都是true
            
            - 方式二(隐式类型转换):    

                - 为任意的数据类型做两次非运算,即可将其转换为布尔值
                - 例子:    
                    var a = "hello";
                    a = !!a; //true

包装类

    - 在JS中为我们提供了三个包装类:String() Boolean() Number()
        - 通过这三个包装类可以创建基本数据类型的对象
        例子:
            var num = new Number(2);
            var str = new String("hello");
            var bool = new Boolean(true);
        - 但是在实际应用中千万不要这么干。
    
    - 当我们去操作一个基本数据类型的属性和方法时,
        解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,
        操作完成以后再将这个临时对象进行销毁。

字符串的相关的方法

    length
        - 获取字符串的长度
    charAt()
        - 根据索引获取指定的字符
    charCodeAt()
        - 根据索引获取指定的字符编码
    String.fromCharCode()
        - 根据字符编码获取字符
    indexOf()
    lastIndexOf()
        - 从一个字符串中检索指定内容
        - 需要一个字符串作为参数,这个字符串就是要检索的内容,如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1。
        - 可以指定一个第二个参数,来表示开始查找的位置
        - indexOf()是从前向后找
        - lastIndexOf()是从后向前找
    slice()
        - 可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量
        - 参数:
            第一个:截取开始的位置(包括开始)
            第二个:截取结束的位置(不包括结束)
                - 可以省略第二个参数,如果省略则一直截取到最后
            - 可以传负数,如果是负数则从后往前数
    substr()    
        - 和slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量
        
    substring()
        - 和slice()基本一致,不同的是它不能接受负值作为参数,如果设置一个负值,则会自动修正为0,substring()中如果第二个参数小于第一个,自动调整位置
    toLowerCase() 
        - 将字符串转换为小写并返回
    toUpperCase() 
        - 将字符串转换为大写并返回
    split()
        - 可以根据指定内容将一个字符串拆分为一个数组
        - 参数:
            - 需要一个字符串作为参数,将会根据字符串去拆分数组
                可以接收一个正则表达式,此时会根据正则表达式去拆分数组
                
    match() 
        - 可以将字符串中和正则表达式匹配的内容提取出来
        - 参数:
            - 正则表达式,可以根据该正则表达式将字符串中符合要求的内容提取出来,并且封装到一个数组中返回
    
    replace()  
        - 可以将字符串中指定内容替换为新的内容
        - 参数:
            - 第一个:被替换的内容,可以是一个正则表达式
            - 第二个:替换的新内容
            
    search() 
        - 可以根据正则表达式去字符串中查找指定的内容
        - 参数:
            正则表达式,将会根据该表达式查询内容,并且将第一个匹配到的内容的索引返回,如果没有匹配到任何内容,则返回-1。

3.3 运算符 

1)运算符

运算符也称为操作符,通过运算符可以对一个或多个值进行运算或操作。

- typeof运算符
    - 用来检查一个变量的数据类型
    - 语法:typeof 变量
    - 它会返回一个用于描述类型的字符串作为结果

- 算数运算符
    +    对两个值进行加法运算并返回结果
    -      对两个值进行减法运算并返回结果
    *    对两个值进行乘法运算并返回结果
    /    对两个值进行除法运算并返回结果
    %    对两个值进行取余运算并返回结果
    
    - 除了加法以外,对非Number类型的值进行运算时,都会先转换为Number然后在做运算。
    - 而做加法运算时,如果是两个字符串进行相加,则会做拼串操作,将两个字符连接为一个字符串。
    - 任何值和字符串做加法,都会先转换为字符串,然后再拼串

<script type="text/javascript">
	
	/*
	 * 运算符也叫操作符
	 * 	通过运算符可以对一个或多个值进行运算,并获取运算结果
	 * 	比如:typeof就是运算符,可以来获得一个值的类型
	 * 		它会将该值的类型以字符串的形式返回
	 * 		number string boolean undefined object
	 * 
	 * 	算数运算符
	 * 		当对非Number类型的值进行运算时,会将这些值转换为Number然后在运算
	 * 			任何值和NaN做运算都得NaN
	 * 
	 * 		+
	 * 			+可以对两个值进行加法运算,并将结果返回
	 * 			 如果对两个字符串进行加法运算,则会做拼串
	 * 				会将两个字符串拼接为一个字符串,并返回
	 * 			任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串的操作
	 * 		-
	 * 			- 可以对两个值进行减法运算,并将结果返回
	 * 
	 * 		*
	 * 			* 可以对两个值进行乘法运算
	 * 		/
	 * 			/ 可以对两个值进行除法运算
	 * 		%
	 * 			% 取模运算(取余数)
	 */
	var a = 123;
	
	var result = typeof a;
	
	//console.log(typeof result);
	
	result = a + 1;
	
	result = 456 + 789;
	
	result = true + 1;
	
	result = true + false;
	
	result = 2 + null;
	
	result = 2 + NaN;
	
	result = "你好" + "大帅哥";
	
	var str = "锄禾日当午," +
			  "汗滴禾下土," +
			  "谁知盘中餐," +
			  "粒粒皆辛苦";
			  
			  
	result = 123 + "1";
	
	result = true + "hello";
	
	//任何值和字符串相加都会转换为字符串,并做拼串操作
	/*
	 * 我们可以利用这一特点,来将一个任意的数据类型转换为String
	 * 	我们只需要为任意的数据类型 + 一个 "" 即可将其转换为String
	 * 	这是一种隐式的类型转换,由浏览器自动完成,实际上它也是调用String()函数
	 */
	var c = 123;
	
	c = c + "";
	
	//c = null;
	
	//c = c + "";
	
	
	//console.log(result);
	//console.log(typeof c);
	//console.log("c = "+c);
	
	result = 1 + 2 + "3"; //33
	
	result = "1" + 2 + 3; //123
	
	result = 100 - 5;
	
	result = 100 - true;
	
	result = 100 - "1";
	
	result = 2 * 2;
	
	result = 2 * "8";
	
	result = 2 * undefined;
	
	result = 2 * null;
	
	result = 4 / 2;
	
	result = 3 / 2;
	
	/*
	 * 任何值做- * /运算时都会自动转换为Number
	 * 	我们可以利用这一特点做隐式的类型转换
	 * 		可以通过为一个值 -0 *1 /1来将其转换为Number
	 * 		原理和Number()函数一样,使用起来更加简单
	 */
	
	var d = "123";
	
	//console.log("result = "+result);
	
	d = d - 0;
	
	/*console.log(typeof d);
	console.log(d);*/
	
	result = 9 % 3;
	result = 9 % 4;
	result = 9 % 5;
	
	console.log("result = "+result);
	
</script>

2)一元运算符

一元运算符只需要一个操作数
① 一元的“+”:就是正号,不会对值产生任何影响,但是可以将一个非数字转换为数字
                - 例子:
                    var a = true;
                    a = +a;
                
② 一元的“-”:就是负号,可以对一个数字进行符号位取反
                - 例子:
                    var a = 10;
                    a = -a;


对于非Number类型的值,它会将先转换为Number,然后再运算。
可以对一个其他的数据类型使用+,来将其转换为number。它的原理和Number()函数一样

3)自增和自减

            - 自增
                - 自增可以使变量在原值的基础上自增1
                - 自增使用 ++
                - 自增可以使用 前++(++a)后++(a++)
                - 无论是++a 还是 a++都会立即使原变量自增1
                    不同的是++a和a++的值是不同的,
                        ++a的值是变量的新值(自增后的值)
                        a++的值是变量的原值(自增前的值)

            - 自减    
                - 自减可以使变量在原值的基础上自减1
                - 自减使用 --
                - 自减可以使用 前--(--a)后--(a--)
                - 无论是--a 还是 a--都会立即使原变量自减1
                    不同的是--a和a--的值是不同的,
                        --a的值是变量的新值(自减后的值)
                        a--的值是变量的原值(自减前的值)

4)逻辑运算符

        ! 非
            - 非运算可以对一个布尔值进行取反,true变false false边true
            - 当对非布尔值使用!时,会先将其转换为布尔值然后再取反
            - 我们可以利用!来将其他的数据类型转换为布尔值
        
        && 与
            - &&可以对符号两侧的值进行与运算
            - 只有两端的值都为true时,才会返回true。只要有一个false就会返回false。
            - 与是一个短路的与,如果第一个值是false,则不再检查第二个值
            - 对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
            - 规则:
                    1.如果第一个值为false,则返回第一个值
                    2.如果第一个值为true,则返回第二个值
        
        || 或
            - ||可以对符号两侧的值进行或运算
            - 只有两端都是false时,才会返回false。只要有一个true,就会返回true。
            - 或是一个短路的或,如果第一个值是true,则不再检查第二个值
            - 对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
            - 规则:    
                    1.如果第一个值为true,则返回第一个值
                    2.如果第一个值为false,则返回第二个值

		<script type="text/javascript">
			
			/*
			 * && || 非布尔值的情况
			 * 	- 对于非布尔值进行与或运算时,
			 * 		会先将其转换为布尔值,然后再运算,并且返回原值
			 * 	- 与运算:
			 * 		- 如果第一个值为true,则必然返回第二个值
			 * 		- 如果第一个值为false,则直接返回第一个值
			 * 
			 * 	- 或运算
			 * 		- 如果第一个值为true,则直接返回第一个值
			 * 		- 如果第一个值为false,则返回第二个值
			 * 
			 */
			
			//true && true
			//与运算:如果两个值都为true,则返回后边的
			var result = 5 && 6;
			
			
			//与运算:如果两个值中有false,则返回靠前的false
			//false && true
			result = 0 && 2;
			result = 2 && 0;
			//false && false
			result = NaN && 0;
			result = 0 && NaN;
			
			
			//true || true
			//如果第一个值为true,则直接返回第一个值
			result = 2 || 1;
			result = 2 || NaN;
			result = 2 || 0;
			
			//如果第一个值为false,则直接返回第二个值
			result = NaN || 1;
			result = NaN || 0;
			
			result = "" || "hello";
			
			result = -1 || "你好";
			
			
			console.log("result = "+result);
			
		</script>

5)赋值运算符

① = :可以将符号右侧的值赋值给左侧变量

② +=

  • a += 5 相当于 a = a+5
  • var str = "hello";  str += "world";

③ -=

  • a -= 5  相当于 a = a-5

④ *=

  • a *= 5 相当于 a = a*5

⑤ /=

  • a /= 5 相当于 a = a/5    

⑥ %=

  • a %= 5 相当于 a = a%5

6)关系运算符

关系运算符用来比较两个值之间的大小关系的。

  • >
  • >=
  • <
  • <=

关系运算符的规则和数学中一致,用来比较两个值之间的关系,如果关系成立则返回true,关系不成立则返回false。

如果比较的两个值是非数值,会将其转换为Number然后再比较。

如果比较的两个值都是字符串,此时会比较字符串的Unicode编码,而不会转换为Number。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">

			//比较两个字符串时,比较的是字符串的字符编码
			//console.log("a" < "b");//true
			//比较字符编码时是一位一位进行比较
			//如果两位一样,则比较下一位,所以借用它来对英文进行排序
			//console.log("abc" < "bcd");//true
			//比较中文时没有意义
			//console.log("戒" > "我"); //true
			
			//如果比较的两个字符串型的数字,可能会得到不可预期的结果
			//注意:在比较两个字符串型的数字时,一定一定一定要转型
			console.log("11123123123123123123" < +"5"); //true

			
			/*
			 * 在字符串中使用转义字符输入Unicode编码
			 * 	\u四位编码
			 */
			console.log("\u2620");
			
		</script>
	</head>
	<body>
		
		<!--在网页中使用Unicode编码
			&#编码; 这里的编码需要的是10进制
		-->
		<h1 style="font-size: 200px;">&#9760;</h1>
		<h1 style="font-size: 200px;">&#9856;</h1>
		
	</body>
</html>

7)相等运算符

==
    - 相等,判断左右两个值是否相等,如果相等返回true,如果不等返回false
    - 相等会自动对两个值进行类型转换,如果对不同的类型进行比较,会将其转换为相同的类型然后再比较,
        转换后相等它也会返回true
!=
    - 不等,判断左右两个值是否不等,如果不等则返回true,如果相等则返回false
    - 不等也会做自动的类型转换。
    
===
    - 全等,判断左右两个值是否全等,它和相等类似,只不过它不会进行自动的类型转换,
        如果两个值的类型不同,则直接返回false
        
!==
    - 不全等,和不等类似,但是它不会进行自动的类型转换,如果两个值的类型不同,它会直接返回true
    
特殊的值:
    - null和undefined
        - 由于undefined衍生自null,所以null == undefined 会返回true。
            但是 null === undefined 会返回false。
            
    - NaN
        - NaN不与任何值相等,报告它自身 NaN == NaN //false
        
    - 判断一个值是否是NaN
        - 使用isNaN()函数

			//console.log(1 == 1); //true
			
			var a = 10;
			
			//console.log(a == 4); //false
			
			//console.log("1" == 1); //true
			
			//console.log(true == "1"); //true
			
			//console.log(null == 0); //false
			
			/*
			 * undefined 衍生自 null
			 * 	所以这两个值做相等判断时,会返回true
			 */
			//console.log(undefined == null);
			
			/*
			 * NaN不和任何值相等,包括他本身
			 */
			//console.log(NaN == NaN); //false
			
			var b = NaN;
			
			//判断b的值是否是NaN
			//console.log(b == NaN);
			/*
			 * 可以通过isNaN()函数来判断一个值是否是NaN
			 * 	如果该值是NaN则返回true,否则返回false
			 */
			//console.log(isNaN(b));
			
			//console.log(10 != 5); //true
			//console.log(10 != 10); //false
			//console.log("abcd" != "abcd"); //false
			//console.log("1" != 1);//false
			
			//console.log("123" === 123);//false
			//console.log(null === undefined);//false
			
			console.log(1 !== "1"); //true

8)三元运算符

条件运算符也叫三元运算符。

        ?:
            - 语法:条件表达式?语句1:语句2;
            - 执行流程:
                先对条件表达式求值判断,
                    如果判断结果为true,则执行语句1,并返回执行结果
                    如果判断结果为false,则执行语句2,并返回执行结果

9)优先级

        - 和数学中一样,JS中的运算符也是具有优先级的,
            比如 先乘除 后加减 先与 后或
        - 具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高,
            优先级越高的越优先计算,优先级相同的,从左往右计算。
        - 优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。

		<script type="text/javascript">
			
			/*
			 * , 运算符
			 * 	使用,可以分割多个语句,一般可以在声明多个变量时使用,
			 */
			//使用,运算符同时声明多个变量
			//var a , b , c;
			
			//可以同时声明多个变量并赋值
			//var a=1 , b=2 , c=3;
			//alert(b);
			
			/*
			 * 就和数学中一样,在JS中运算符也有优先级,
			 * 	比如:先乘除 后加减
			 * 在JS中有一个运算符优先级的表,
			 * 	在表中越靠上优先级越高,优先级越高越优先计算,
			 * 	如果优先级一样,则从左往右计算。
			 * 但是这个表我们并不需要记忆,如果遇到优先级不清楚
			 * 	可以使用()来改变优先级
			 */
			
			//var result = 1 + 2 * 3;
			
			/*
			 * 如果||的优先级高,或者两个一样高,则应该返回3
			 * 如果与的优先级高,则应该返回1
			 * 		
			 */
			var result = 1 || 2 && 3;
			
			console.log("result = "+result);	
			
		</script>

3.4 流程控制语句

		<script type="text/javascript">
			
			/*
			 * 我们的程序是由一条一条语句构成的
			 * 	语句是按照自上向下的顺序一条一条执行的
			 * 	在JS中可以使用{}来为语句进行分组,
			 * 		同一个{}中的语句我们称为是一组语句,
			 * 		它们要么都执行,要么都不执行,
			 * 		一个{}中的语句我们也称为叫一个代码块
			 * 		在代码块的后边就不用再编写;了
			 * 
			 * 	JS中的代码块,只具有分组的的作用,没有其他的用途
			 * 		代码块内容的内容,在外部是完全可见的
			 */
			{
				var a = 10;	
				alert("hello");
				console.log("你好");
				document.write("语句");
			}
			
			console.log("a = "+a);
		</script>

程序都是自上向下的顺序执行的,通过流程控制语句可以改变程序执行的顺序,或者反复的执行某一段的程序。

分类:

  • 条件判断语句
  • 条件分支语句
  • 循环语句

1)条件判断语句

- 条件判断语句也称为if语句
- 语法一:
    if(条件表达式){
        语句...
    }
    
    - 执行流程:
        if语句执行时,会先对条件表达式进行求值判断,如果值为true,则执行if后的语句,如果值为false,则不执行。

    

- 语法二:
    if(条件表达式){
        语句...
    }else{
        语句...
    }
    
    - 执行流程:
        if...else语句执行时,会对条件表达式进行求值判断,如果值为true,则执行if后的语句,如果值为false,则执行else后的语句。
    
- 语法三:
    if(条件表达式){
        语句...
    }else if(条件表达式){
        语句...
    }else if(条件表达式){
        语句...
    }else if(条件表达式){
        语句...
    }else{
        语句...
    }
    
    - 执行流程
        - if...else if...else语句执行时,会自上至下依次对条件表达式进行求值判断,如果判断结果为true,则执行当前if后的语句,执行完成后语句结束。

如果判断结果为false,则继续向下判断,直到找到为true的为止。如果所有的条件表达式都是false,则执行else后的语句

2)条件分支语句

条件分支语句也叫switch语句。
    - 语法:
        switch(条件表达式){
            case 表达式:
                语句...
                break;
            case 表达式:
                语句...
                break;
            case 表达式:
                语句...
                break;
            default:
                语句...
                break;
        }

        
    - 执行流程:
        - switch...case..语句在执行时,会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较,如果比较结果为true,则从当前case处开始执行代码。当前case后的所有的代码都会执行,我们可以在case的后边跟着一个break关键字,这样可以确保只会执行当前case后的语句,而不会执行其他的case。如果比较结果为false,则继续向下比较,如果所有的比较结果都为false,则只执行default后的语句。

3)循环语句

    - 通过循环语句可以反复执行某些语句多次
    - while循环

        - 语法:
            while(条件表达式){
                语句...
            }

            
        - 执行流程:
            while语句在执行时,会先对条件表达式进行求值判断,如果判断结果为false,则终止循环。如果判断结果为true,则执行循环体,循环体执行完毕,继续对条件表达式进行求值判断,依此类推。
                
    - do...while循环
        - 语法:
            do{
                语句...
            }while(条件表达式)
            
        - 执行流程
            do...while在执行时,会先执行do后的循环体,然后在对条件表达式进行判断,如果判断判断结果为false,则终止循环。如果判断结果为true,则继续执行循环体,依此类推。
                
        - 和while的区别:
            while:先判断后执行
            do...while: 先执行后判断
            - do...while可以确保循环体至少执行一次。

            
            
    - for循环
        - 语法:
            for(①初始化表达式 ; ②条件表达式 ; ④更新表达式){
                ③语句...
            }
        - 执行流程:
            首先执行①初始化表达式,初始化一个变量, 然后对②条件表达式进行求值判断,如果为false则终止循环。

如果判断结果为true,则执行③循环体,循环体执行完毕,执行④更新表达式,对变量进行更新。更新表达式执行完毕重复②
            
    - 死循环
        while(true){
        
        }
        
        for(;;){
        
        }

3.5 对象(Object)

对象是JS中的引用数据类型。对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性。使用typeof检查一个对象时,会返回object。

    - 创建对象
        - 方式一:
            - var obj = new Object();
        - 方式二:
            - var obj = {};
            
    - 向对象中添加属性
        - 语法:
            对象.属性名 = 属性值;
            对象["属性名"] = 属性值;
            
            - 对象的属性名没有任何要求,不需要遵守标识符的规范,但是在开发中,尽量按照标识符的要求去写。
            - 属性值也可以任意的数据类型。

            

    - 读取对象中的属性
        - 语法:
            对象.属性名
            对象["属性名"]
        - 如果读取一个对象中没有的属性,它不会报错,而是返回一个undefined
        
    - 删除对象中的属性
        - 语法:
            delete 对象.属性名
            delete 对象["属性名"]
            
    - 使用in检查对象中是否含有指定属性
        - 语法:"属性名" in 对象
            - 如果在对象中含有该属性,则返回true
                如果没有则返回false
                
    - 使用对象字面量,在创建对象时直接向对象中添加属性
        语法:
            var obj = {
                            属性名:属性值,
                            属性名:属性值,
                            属性名:属性值,
                            属性名:属性值
                    }
                    
    - 基本数据类型和引用数据类型
        - 基本数据类型:String Number Boolean Null Undefined
        - 引用数据类型:Object


        - 基本数据类型的数据,变量是直接保存的它的值。变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。
        - 引用数据类型的数据,变量是保存的对象的引用(内存地址)。如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。
        - 比较两个变量时,对于基本数据类型,比较的就是值,对于引用数据类型比较的是地址,地址相同才相同。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			/*
			 * JS中数据类型
			 * 	- String 字符串
			 *  - Number 数值
			 * 	- Boolean 布尔值
			 * 	- Null 空值
			 * 	- Undefined 未定义
			 * 		- 以上这五种类型属于基本数据类型,以后我们看到的值
			 * 			只要不是上边的5种,全都是对象
			 * 	- Object 对象
			 * 
			 * 
			 * 基本数据类型都是单一的值"hello" 123 true,
			 * 	值和值之间没有任何的联系。
			 * 
			 * 在JS中来表示一个人的信息(name gender age):
			 * 	var name = "孙悟空";
			 * 	var gender = "男";
			 * 	var age = 18;
			 * 如果使用基本数据类型的数据,我们所创建的变量都是独立,不能成为一个整体。
			 * 
			 * 对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
			 * 
			 * 对象的分类:
			 * 	1.内建对象
			 * 		- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
			 * 		- 比如:Math String Number Boolean Function Object....
			 * 
			 * 	2.宿主对象
			 * 		- 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
			 * 		- 比如 BOM DOM
			 * 
			 * 	3.自定义对象
			 * 		- 由开发人员自己创建的对象
			 * 
			 */
			
			//创建对象
			/*
			 * 使用new关键字调用的函数,是构造函数constructor
			 * 	构造函数是专门用来创建对象的函数
			 * 使用typeof检查一个对象时,会返回object
			 */
			var obj = new Object();
			
			
			/*
			 * 在对象中保存的值称为属性
			 * 向对象添加属性
			 * 	语法:对象.属性名 = 属性值;
			 */
			
			//向obj中添加一个name属性
			obj.name = "孙悟空";
			//向obj中添加一个gender属性
			obj.gender = "男";
			//向obj中添加一个age属性
			obj.age = 18;
			
			/*
			 * 读取对象中的属性
			 * 	语法:对象.属性名
			 * 
			 * 如果读取对象中没有的属性,不会报错而是会返回undefined
			 */
			
			//console.log(obj.gender);
			//console.log(obj.hello);
			
			/*
			 * 修改对象的属性值
			 * 	语法:对象.属性名 = 新值
			 */
			obj.name = "tom";
			
			/*
			 * 删除对象的属性
			 * 	语法:delete 对象.属性名
			 */
			delete obj.name;
			console.log(obj.age);
		</script>
	</head>
	<body>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
			var obj = new Object();

			/*
			 * 向对象中添加属性
			 * 属性名:
			 * 	- 对象的属性名不强制要求遵守标识符的规范
			 * 		什么乱七八糟的名字都可以使用
			 * 	- 但是我们使用是还是尽量按照标识符的规范去做
			 * 
			 */
			obj.name = "孙悟空";
			
			//obj.var = "hello";
			
			/*
			 * 如果要使用特殊的属性名,不能采用.的方式来操作
			 * 	需要使用另一种方式:
			 * 		语法:对象["属性名"] = 属性值
			 * 	读取时也需要采用这种方式
			 * 
			 * 使用[]这种形式去操作属性,更加的灵活,
			 * 	在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
			 * 
			 */
			obj["123"] = 789;
			obj["nihao"] = "你好";
			var n = "nihao";
			//console.log(obj["123"]);
			
			/*
			 * 属性值
			 * 	JS对象的属性值,可以是任意的数据类型,甚至也可以是一个对象
			 */
			
			obj.test = true;
			obj.test = null;
			obj.test = undefined;
			
			//创建一个对象
			var obj2 = new Object();
			obj2.name = "猪八戒";
			
			//将obj2设置为obj的属性
			obj.test = obj2;
			
			//console.log(obj.test.name);
			
			/*
			 * in 运算符
			 * 	- 通过该运算符可以检查一个对象中是否含有指定的属性
			 * 		如果有则返回true,没有则返回false
			 *  - 语法:
			 * 		"属性名" in 对象
			 */
			//console.log(obj.test2);
			
			//检查obj中是否含有test2属性
			//console.log("test2" in obj);
			//console.log("test" in obj);
			console.log("name" in obj);

			/*
			 * 使用对象字面量,可以在创建对象时,直接指定对象中的属性
			 * 语法:{属性名:属性值,属性名:属性值....}
			 * 对象字面量的属性名可以加引号也可以不加,建议不加,如果要使用一些特殊的名字,则必须加引号
			 * 
			 * 属性名和属性值是一组一组的名值对结构,名和值之间使用:连接,多个名值对之间使用,隔开;
			 * 	如果一个属性之后没有其他的属性了,就不要写,
			 */
			var obj2 = {
				
				name:"猪八戒",
				age:13,
				gender:"男",
				test:{name:"沙僧"}
				
			};
			
			console.log(obj2.test);
			
		</script>
	</head>
	<body>
	</body>
</html>

JS中的变量都是保存到栈内存中的,基本数据类型的值直接在栈内存中存储,值与值之间是独立存在,修改一个变量不会影响其他的变量。

对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
			/*
			 * 创建一个对象
			 */
			var obj = {
					name:"孙悟空",
					age:18,
					gender:"男",
					sayName:function(){
						alert(this.name);
					}
			};

			/*
			 * 使用工厂方法创建对象
			 * 	通过该方法可以大批量的创建对象
			 */
			function createPerson(name , age ,gender){
				//创建一个新的对象 
				var obj = new Object();
				//向对象中添加属性
				obj.name = name;
				obj.age = age;
				obj.gender = gender;
				obj.sayName = function(){
					alert(this.name);
				};
				//将新的对象返回
				return obj;
			}
			
			/*
			 * 用来创建狗的对象
			 */
			function createDog(name , age){
				var obj = new Object();
				obj.name = name;
				obj.age = age;
				obj.sayHello = function(){
					alert("汪汪~~");
				};
				
				return obj;
			}
			
			var obj2 = createPerson("猪八戒",28,"男");
			var obj3 = createPerson("白骨精",16,"女");
			var obj4 = createPerson("蜘蛛精",18,"女");
			/*
			 * 使用工厂方法创建的对象,使用的构造函数都是Object
			 * 	所以创建的对象都是Object这个类型,
			 * 	就导致我们无法区分出多种不同类型的对象
			 */
			//创建一个狗的对象
			var dog = createDog("旺财",3);
			
			console.log(dog);
			console.log(obj4);
			
		</script>
	</head>
	<body>
	</body>
</html>

3.6 函数(Function)

函数也是一个对象,也具有普通对象的功能。函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码。使用typeof检查一个函数时会返回function。

1)创建函数

① 函数声明

function 函数名([形参1,形参2...形参N]){
                语句...
            }

2)函数表达式  (匿名函数,不常用)

var 函数名 = function([形参1,形参2...形参N]){
                语句...
            };
			/*
			 * 函数 function
			 * 	- 函数也是一个对象
			 * 	- 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
			 * 	- 函数中可以保存一些代码在需要的时候调用
			 * 	- 使用typeof检查一个函数对象时,会返回function
			 */
			
			//我们在实际开发中很少使用构造函数来创建一个函数对象
			//创建一个函数对象
			//可以将要封装的代码以字符串的形式传递给构造函数
			//var fun = new Function("console.log('Hello 这是我的第一个函数');");
			
			//封装到函数中的代码不会立即执行
			//函数中的代码会在函数调用的时候执行
			//调用函数 语法:函数对象()
			//当调用函数时,函数中封装的代码会按照顺序执行
			//fun();
			
			/*
			 * 使用 函数声明 来创建一个函数
			 * 	语法:
			 * 		function 函数名([形参1,形参2...形参N]){
			 * 			语句...
			 * 		}
			 */
			
			function fun2(){
				console.log("这是我的第二个函数~~~");
				alert("哈哈哈哈哈");
				document.write("~~~~(>_<)~~~~");
			}
			
			//console.log(fun2);
			//调用fun2
			//fun2();
			
			/*
			 * 使用 函数表达式 来创建一个函数
			 * var 函数名  = function([形参1,形参2...形参N]){
			 * 	 语句....
			 *  }
			 */
			
			var fun3 = function(){
				console.log("我是匿名函数中封装的代码");
			};
			
			fun3();
			/*
			 * 创建一个对象
			 */
			var obj = new Object();
			
			//向对象中添加属性
			obj.name = "孙悟空";
			obj.age = 18;
			
			//对象的属性值可以是任何的数据类型,也可以是个函数
			obj.sayName = function(){
				console.log(obj.name);
			};
			
			function fun(){
				console.log(obj.name);
			};
			
			//console.log(obj.sayName);
			//调方法
			obj.sayName();
			//调函数
			fun();
			
			/*
			 * 函数也可以称为对象的属性,
			 * 	如果一个函数作为一个对象的属性保存,
			 * 	那么我们称这个函数时这个对象的方法
			 * 	调用这个函数就说调用对象的方法(method)
			 * 
			 * 但是它只是名称上的区别没有其他的区别
			 * 
			 */
			
			var obj2 = {
				name:"猪八戒",
				age:18,
				sayName:function(){
					console.log(obj2.name);
				}
			};
			
			obj2.sayName();

2)调用函数

① 语法:函数对象([实参1,实参2...实参N]);

fun()
sum()
alert()
Number()
parseInt()

当我们调用函数时,函数中封装的代码会按照编写的顺序执行

② 形参和实参

        - 形参:形式参数
            - 定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开
                定义形参就相当于在函数内声明了对应的变量但是并不赋值,
                形参会在调用时才赋值。
                
        - 实参:实际参数
            - 调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,
                调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。
                如果实参的数量大于形参,多余实参将不会赋值,
                如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined

			/*
			 * 定义一个用来求两个数和的函数
			 * 	可以在函数的()中来指定一个或多个形参(形式参数)
			 * 	多个形参之间使用,隔开,声明形参就相当于在函数内部声明了对应的变量
			 * 	但是并不赋值
			 */
			function sum(a,b){
				console.log("a = "+a);
				console.log("b = "+b);
				console.log(a+b);
			}
			
			/*
			 * 在调用函数时,可以在()中指定实参(实际参数)
			 * 	实参将会赋值给函数中对应的形参
			 */
			/*sum(1,2);
			sum(123,456);*/
			
			/*
			 * 调用函数时解析器不会检查实参的类型,
			 * 	所以要注意,是否有可能会接收到非法的参数,如果有可能则需要对参数进行类型的检查
			 * 函数的实参可以是任意的数据类型
			 */
			//sum(123,"hello");
			//sum(true , false);
			
			/*
			 * 调用函数时,解析器也不会检查实参的数量
			 * 	多余实参不会被赋值
			 * 如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
			 * 
			 */
			//sum(123,456,"hello",true,null);
			sum(123);

			/*
			 * 创建一个函数,可以在控制台中输出一个人的信息
			 * 	可以输出人的 name age gender address
			 * 
			 * 实参可以是任意的数据类型,也可以是一个对象
			 * 	当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递
			 */
			function sayHello(o){
				
				//console.log("o = "+o);
				console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+"人"+",我住在"+o.address);
			}
			
			//创建一个对象
			var obj = {
				name:"孙悟空",
				age:18,
				address:"花果山",
				gender:"男"
				
			};
			
			sayHello(obj);

			/*
			 * 实参可以是一个对象,也可以是一个函数
			 */
			
			function fun(a){
				console.log("a = "+a);
				//a(obj);
			}
			
			//fun(sayHello);
			
			//fun(function(){alert("hello")});
			
			fun(mianji(10));

3)返回值

返回值,就是函数执行的结果。

        - 使用return 来设置函数的返回值。
        - 语法:return 值;
            - 该值就会成为函数的返回值,可以通过一个变量来接收返回值
        - return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。
        - return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象。
        - 如果return后不跟值,或者是不写return则函数默认返回undefined。
        - break、continue和return
            - break
                - 退出循环
            - continue
                - 跳过当次循环
            - return
                - 退出函数

			/*
			 * mianji()
			 * 	- 调用函数
			 * 	- 相当于使用的函数的返回值
			 * 
			 * mianji
			 * 	- 函数对象
			 * 	- 相当于直接使用函数对象
			 */


			/*
			 * 返回值可以是任意的数据类型
			 * 	也可以是一个对象,也可以是一个函数
			 */
			function fun2(){
				
				//返回一个对象
				return {name:"沙和尚"};
			}

4)参数

函数的实参也可以是任意的数据类型。

5)方法(method)

可以将一个函数设置为一个对象的属性,当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。

对象.方法名();

函数名(); 

立即执行函数:

			//函数对象()
			/*
			 * 立即执行函数
			 * 	函数定义完,立即被调用,这种函数叫做立即执行函数
			 * 	立即执行函数往往只会执行一次
			 */
			/*(function(){
				alert("我是一个匿名函数~~~");
			})();*/
			
            //在匿名函数后面直接加(123,456)执行函数
			(function(a,b){
				console.log("a = "+a);
				console.log("b = "+b);
			})(123,456);

call()、apply()

这两个方法都是函数对象的方法需要通过函数对象来调用,通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this,不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递。

arguments

arguments和this类似,都是函数中的隐含的参数。arguments是一个类数组元素,它用来封装函数执行过程中的实参,所以即使不定义形参,也可以通过arguments来使用实参。

arguments中有一个属性callee表示当前执行的函数对象。

3.7 作用域

作用域简单来说就是一个变量的作用范围。

在JS中作用域分成两种:

1)全局作用域

            - 直接在script标签中编写的代码都运行在全局作用域中
            - 全局作用域在打开页面时创建,在页面关闭时销毁。
            - 全局作用域中有一个全局对象window,window对象由浏览器提供,可以在页面中直接使用,它代表的是整个的浏览器的窗口。
            - 在全局作用域中创建的变量都会作为window对象的属性保存,在全局作用域中创建的函数都会作为window对象的方法保存
            - 在全局作用域中创建的变量和函数可以在页面的任意位置访问。在函数作用域中也可以访问到全局作用域的变量。
            - 尽量不要在全局中创建变量    

2)函数作用域

            - 函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。
            - 函数作用域在函数执行时创建,在函数执行结束时销毁。
            - 在函数作用域中创建的变量,不能在全局中访问。
            - 当在函数作用域中使用一个变量时,它会先在自身作用域中寻找,如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,如果找到了则使用,找不到则继续向上找。

3)变量的声明提前

会在所有的代码执行之前被声明,但是不会赋值。 所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前。

在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明,如果没有使用var关键字声明变量,则变量会变成全局变量。

4)函数的声明提前

在全局作用域中,使用函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建,也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性。

在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了。

			/*
			 * 变量的声明提前
			 * 	- 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值),
			 * 		但是如果声明变量时不适用var关键字,则变量不会被声明提前
			 * 
			 * 函数的声明提前
			 * 	- 使用函数声明形式创建的函数 function 函数(){}
			 * 		它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数
			 * 	   使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用	
			 */
			/*console.log("a = "+a); //报错
			var a = 123;*/
			
			//fun(); //不报错
			
			//函数声明,会被提前创建
			function fun(){
				console.log("我是一个fun函数");
			}
			
			//函数表达式,不会被提前创建
			var fun2 = function(){
				console.log("我是fun2函数");
			};
			
			fun2();

3.8 this(上下文对象)

我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。

  1. 以函数的形式调用时,this是window
  2. 以方法的形式调用时,this是调用方法的对象
  3. 以构造函数的形式调用时,this是新建的那个对象
  4. 使用call和apply调用时,this是指定的那个对象
  5. 在全局作用域中this代表window
			/*
			 * 解析器在调用函数每次都会向函数内部传递进一个隐含的参数,
			 * 	这个隐含的参数就是this,this指向的是一个对象,
			 * 	这个对象我们称为函数执行的 上下文对象,
			 * 	根据函数的调用方式的不同,this会指向不同的对象
			 * 		1.以函数的形式调用时,this永远都是window
			 * 		2.以方法的形式调用时,this就是调用方法的那个对象
			 */
			function fun(){
				//console.log("a = "+a+", b = "+b);
				console.log(this.name);
			}
			
			//创建一个对象
			var obj = {
				name:"孙悟空",
				sayName:fun
			};
			
			var obj2 = {
				name:"沙和尚",
				sayName:fun
			};
			
			//console.log(obj.sayName == fun);
			var name = "全局的name属性";

			//以函数形式调用,this是window
			//fun(); //全局的name属性
			
			//以方法的形式调用,this是调用方法的对象
			//obj.sayName(); //孙悟空
			obj2.sayName(); //沙和尚

3.9 构造函数

构造函数是专门用来创建对象的函数,一个构造函数我们也可以称为一个类。

通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例,通过同一个构造函数创建的对象,我们称为一类对象。

构造函数就是一个普通的函数,只是他的调用方式不同,如果直接调用,它就是一个普通函数; 如果使用new来调用,则它就是一个构造函数。

例子:

        function Person(){
        
        }

1)构造函数的执行流程

  1. 创建一个新的对象
  2. 将新的对象作为函数的上下文对象(this)
  3. 执行函数中的代码
  4. 将新建的对象返回

2)instanceof 用来检查一个对象是否是一个类的实例。

如果该对象时构造函数的实例,则返回true,否则返回false;Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true。

语法:对象 instanceof 构造函数

			/*
			 * 创建一个构造函数,专门用来创建Person对象的
			 * 	构造函数就是一个普通的函数,创建方式和普通函数没有区别,
			 * 	不同的是构造函数习惯上首字母大写
			 * 
			 * 构造函数和普通函数的区别就是调用方式的不同
			 * 	普通函数是直接调用,而构造函数需要使用new关键字来调用
			 * 
			 * 构造函数的执行流程:
			 * 	1.立刻创建一个新的对象
			 * 	2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象
			 * 	3.逐行执行函数中的代码
			 * 	4.将新建的对象作为返回值返回
			 * 
			 * 使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。
			 * 	我们将通过一个构造函数创建的对象,称为是该类的实例
			 * 
			 * this的情况:
			 * 	1.当以函数的形式调用时,this是window
			 * 	2.当以方法的形式调用时,谁调用方法this就是谁
			 * 	3.当以构造函数的形式调用时,this就是新创建的那个对象
			 * 
			 */
			function Person(name , age , gender){
				this.name = name;
				this.age = age;
				this.gender = gender;
				this.sayName = function(){
					alert(this.name);
				};
			}
			
			function Dog(){
				
			}
			
			var per = new Person("孙悟空",18,"男");
			var per2 = new Person("玉兔精",16,"女");
			var per3 = new Person("奔波霸",38,"男");
			
			var dog = new Dog();
			
			/*console.log(per);
			console.log(dog);*/
			
			/*
			 * 使用instanceof可以检查一个对象是否是一个类的实例
			 * 	语法:
			 * 		对象 instanceof 构造函数
			 * 如果是,则返回true,否则返回false
			 */
			//console.log(per instanceof Person);
			//console.log(dog instanceof Person);
			
			/*
			 * 所有的对象都是Object的后代,
			 * 	所以任何对象和Object左instanceof检查时都会返回true
			 */
			//console.log(dog instanceof Object);

3)枚举对象中的属性:for...in

 语法:

            for(var 属性名 in 对象){
            
            }

 for...in 语句的循环体会执行多次,对象中有几个属性就会执行几次,每次将一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性。

			var obj = {
						name:"孙悟空",
						age:18,
						gender:"男",
						address:"花果山"
					 };
					 
			//枚举对象中的属性
			//使用for ... in 语句
			/*
			 * 语法:
			 * 	for(var 变量 in 对象){
			 * 	
			 *  }
			 * 
			 * for...in语句 对象中有几个属性,循环体就会执行几次
			 * 	每次执行时,会将对象中的一个属性的名字赋值给变量
			 */
			
			for(var n in obj){
				console.log("属性名:"+n);
				console.log("属性值:"+obj[n]);
			}

3.10 原型(prototype)

创建一个函数以后,解析器都会默认在函数中添加一个数prototype,prototype属性指向的是一个对象,这个对象我们称为原型对象。当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。这个隐含的属性可以通过对象.__proto__来访问。

原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。我们可以将对象中共有的属性和方法统一添加到原型对象中,这样我们只需要添加一次,就可以使所有的对象都可以使用。

当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,如果在自身中找到了,则直接使用。如果没有找到,则去原型对象中寻找,如果找到了则使用,如果没有找到,则去原型的原型中寻找,依此类推。直到找到Object的原型为止,Object的原型的原型为null,如果依然没有找到则返回undefined。

hasOwnProperty():这个方法可以用来检查对象自身中是否含有某个属性。

语法:

对象.hasOwnProperty("属性名")
			/*
			 * 原型 prototype
			 * 
			 * 	我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
			 * 		这个属性对应着一个对象,这个对象就是我们所谓的原型对象
			 * 	如果函数作为普通函数调用prototype没有任何作用
			 * 	当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,
			 * 		指向该构造函数的原型对象,我们可以通过__proto__来访问该属性
			 * 
			 * 	原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,
			 * 		我们可以将对象中共有的内容,统一设置到原型对象中。
			 * 
			 * 当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,
			 * 	如果没有则会去原型对象中寻找,如果找到则直接使用
			 * 
			 * 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,
			 * 	这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
			 */
			
			function MyClass(){
				
			}
			
			//向MyClass的原型中添加属性a
			MyClass.prototype.a = 123;
			
			//向MyClass的原型中添加一个方法
			MyClass.prototype.sayHello = function(){
				alert("hello");
			};
			
			var mc = new MyClass();
			var mc2 = new MyClass();
			
			//console.log(MyClass.prototype);
			//console.log(mc2.__proto__ == MyClass.prototype);
			
			//向mc中添加a属性
			mc.a = "我是mc中的a";
			//console.log(mc2.a);
			mc.sayHello();
			/*
			 * 创建一个构造函数
			 */
			function MyClass(){
				
			}
			
			//向MyClass的原型中添加一个name属性
			MyClass.prototype.name = "我是原型中的名字";
			
			var mc = new MyClass();
			mc.age = 18;
			
			//console.log(mc.name);
			
			//使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
			//console.log("name" in mc);
			
			//可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
			//使用该方法只有当对象自身中含有属性时,才会返回true(自己没有,原型有也是false)
			// console.log(mc.hasOwnProperty("name")); //false
			// console.log(mc.hasOwnProperty("age")); //true

			// console.log(mc.hasOwnProperty("hasOwnProperty")); //false hasOwnProperty方法也在原型了
			
			/*
			 * 原型对象也是对象,所以它也有原型,
			 * 	当我们使用一个对象的属性或方法时,会现在自身中寻找,
			 * 		自身中如果有,则直接使用,
			 * 		如果没有则去原型对象中寻找,如果原型对象中有,则使用,
			 * 		如果没有则去原型的原型中寻找,直到找到Object对象的原型,
			 * 		Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined
			 */
			
			// console.log(mc.__proto__.hasOwnProperty("hasOwnProperty")); //false
			
			// console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty")); //true hasOwnProperty方法在原型的原型里
			// console.log(mc.__proto__.__proto__.__proto__); //null
			// console.log(mc.hello); //undefined
			// console.log(mc.__proto__.__proto__.__proto__) //null

3.11 数组(Array)

数组也是一个对象,是一个用来存储数据的对象,和Object类似,但是它的存储效率比普通对象要高。数组中保存的内容我们称为元素,数组使用索引(index)来操作元素,索引指由0开始的整数。

1)数组的操作

① 创建数组

var arr = new Array();
var arr = [];

② 向数组中添加元素

// 数组对象[索引] = 值;
arr[0] = 123;
arr[1] = "hello";

③  创建数组时直接添加元素

// var arr = [元素1,元素2....元素N];
var arr = [123,"hello",true,null];

④ 获取和修改数组的长度

使用length属性来操作数组的长度。

a)获取长度:

数组.length

length获取到的是数组的最大索引+1。对于连续的数组,length获取到的就是数组中元素的个数。

b)修改数组的长度

数组.length = 新长度

如果修改后的length大于原长度,则多出的部分会空出来;如果修改后的length小于原长度,则原数组中多出的元素会被删除。

c)向数组的最后添加元素

数组[数组.length] = 值;

2)数组的方法

① push()

用来向数组的末尾添加一个或多个元素,并返回数组新的长度

语法:数组.push(元素1,元素2,元素N)

② pop()

用来删除数组的最后一个元素,并返回被删除的元素

③ unshift()

向数组的前边添加一个或多个元素,并返回数组的新的长度

④ shift()

删除数组的前边的一个元素,并返回被删除的元素

⑤ slice()

可以从一个数组中截取指定的元素,该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回。

参数:

  • 截取开始位置的索引(包括开始位置)
  • 截取结束位置的索引(不包括结束位置)

第二个参数可以省略不写,如果不写则一直截取到最后。参数可以传递一个负值,如果是负值,则从后往前数。

⑥ splice()

可以用来删除数组中指定元素,并使用新的元素替换。该方法会将删除的元素封装到新数组中返回。

参数:

  • 删除开始位置的索引
  • 删除的个数
  • 三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边

⑦ reverse()

可以用来反转一个数组,它会对原数组产生影响

⑧ concat()

可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回

⑨ join()

可以将一个数组转换为一个字符串

参数: 需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素,如果不指定连接符则默认使用。

⑩ sort()

可以对一个数组中的内容进行排序,默认是按照Unicode编码进行排序,调用以后,会直接修改原数组。

可以自己指定排序的规则,需要一个回调函数作为参数:

function(a,b){
                
    //升序排列
    //return a-b;
                
    //降序排列
    return b-a;
}

3)遍历数组

遍历数组就是将数组中元素都获取到。

① 一般情况我们都是使用 for 循环来遍历数组:

for(var i=0 ; i<数组.length ; i++){
    //数组[i]
}

② 使用 forEach() 方法来遍历数组(不兼容IE8)

数组.forEach(function(value , index , obj){

});
  • forEach()方法需要一个回调函数作为参数,数组中有几个元素,回调函数就会被调用几次,每次调用时,都会将遍历到的信息以实参的形式传递进来,我们可以定义形参来获取这些信息。
  • value:正在遍历的元素
  • index:正在遍历元素的索引
  •  obj:被遍历对象

3.12 正则表达式

正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,也可以将一个字符串中符合规则的内容提取出来。

    - 创建正则表达式
        - var reg = new RegExp("正则","匹配模式");
        - var reg = /正则表达式/匹配模式
        
    - 语法:
        匹配模式:
            i:忽略大小写
            g:全局匹配模式
            - 设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求
            
        正则语法        
            | 或
            [] 或
            [^ ] 除了
            [a-z] 小写字母
            [A-Z] 大写字母
            [A-z] 任意字母
            [0-9] 任意数字
            
    - 方法:
        test()
            - 可以用来检查一个字符串是否符合正则表达式
            - 如果符合返回true,否则返回false

    

--------------------------------

    

    - 语法:
        - 量词
            {n} 正好n次
            {m,n} m-n次
            {m,} 至少m次
            +    至少1次 {1,}
            ?   0次或1次 {0,1}
            *   0次或多次 {0,}
            
        - 转义字符
            \ 在正则表达式中使用\作为转义字符
            \. 表示.
            \\ 表示\
            . 表示任意字符
            \w
                - 相当于[A-z0-9_]
            \W
                - 相当于[^A-z0-9_]
            \d
                - 任意数字
            \D
                - 除了数字
            \s
                - 空格
            \S
                - 除了空格
            \b
                - 单词边界
            \B
                - 除了单词边界
        ^ 表示开始
        $ 表示结束

3.13 Date

日期的对象,在JS中通过Date对象来表示一个时间

    - 创建对象
        - 创建一个当前的时间对象
            var d = new Date();
        - 创建一个指定的时间对象
            var d = new Date("月/日/年 时:分:秒");
            
    - 方法:
        getDate()
            - 当前日期对象是几日(1-31)
            
        getDay() 
            - 返回当前日期对象时周几(0-6)
                - 0 周日
                - 1 周一 。。。
                
        getMonth()
            - 返回当前日期对象的月份(0-11)
            - 0 一月 1 二月 。。。
        getFullYear() 从 Date 对象以四位数字返回年份。 
        
        getHours() 返回 Date 对象的小时 (0 ~ 23)。 
        getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 
        getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 
        getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 
        
        getTime()
            - 返回当前日期对象的时间戳
            - 时间戳,指的是从1970年月1日 0时0分0秒,到现在时间的毫秒数
                计算机底层保存时间都是以时间戳的形式保存的。
                
        Date.now()
            - 可以获取当前代码执行时的时间戳

3.14 Math

    - Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法。我们可以直接使用它来进行数学运算相关的操作。

                 
    - 方法:
        Math.PI
            - 常量,圆周率
        Math.abs()
            - 绝对值运算
        Math.ceil()
            - 向上取整
        Math.floor()
            - 向下取整
        Math.round()
            - 四舍五入取整
        Math.random()    
            - 生成一个0-1之间的随机数
            - 生成一个x-y之间的随机数
                Math.round(Math.random()*(y-x)+x);
        Math.pow(x,y)
            - 求x的y次幂
        Math.sqrt()
            - 对一个数进行开方
        Math.max()
            - 求多个数中最大值
        Math.min()
            - 求多个数中的最小值

3.15 DOM

    - Document Object Model,文档对象模型,通过DOM可以来任意来修改网页中各个内容。
    - 文档
        - 文档指的是网页,一个网页就是一个文档
    - 对象
        - 对象指将网页中的每一个节点都转换为对象,转换完对象以后,就可以以一种纯面向对象的形式来操作网页了。
    - 模型
        - 模型用来表示节点和节点之间的关系,方便操作页面。
    - 节点(Node)
        - 节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点,虽然都是节点,但是节点的类型却是不同的。
        - 常用的节点
            - 文档节点 (Document),代表整个网页
            - 元素节点(Element),代表网页中的标签
            - 属性节点(Attribute),代表标签中的属性
            - 文本节点(Text),代表网页中的文本内容

1)DOM操作

        - DOM查询
        - 在网页中浏览器已经为我们提供了document对象,它代表的是整个网页,它是window对象的属性,可以在页面中直接使用。
        - document查询方法:
            - 根据元素的id属性查询一个元素节点对象:document.getElementById("id属性值");
            - 根据元素的name属性值查询一组元素节点对象:document.getElementsByName("name属性值");
            - 根据标签名来查询一组元素节点对象:document.getElementsByTagName("标签名");
                
        - 元素的属性:
            - 读取元素的属性:
                语法:元素.属性名
                例子:ele.name  
                      ele.id  
                      ele.value 
                      ele.className
                      
            - 修改元素的属性:
                语法:元素.属性名 = 属性值
                
            - innerHTML
                - 使用该属性可以获取或设置元素内部的HTML代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<button id="btn">我是一个按钮</button>
		<script type="text/javascript">
			
			/*
			 * 浏览器已经为我们提供 文档节点 对象这个对象是window属性
			 * 	可以在页面中直接使用,文档节点代表的是整个网页
			 */
			//console.log(document);
			
			//获取到button对象
			var btn = document.getElementById("btn");
			
			//修改按钮的文字
			btn.innerHTML = "I'm Button";
			
			
		</script>
	</body>
</html>

2)事件(Event)

事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。我们可以为事件来绑定回调函数来响应事件。

绑定事件的方式:

① 可以在标签的事件属性中设置相应的JS代码

 <button onclick="js代码。。。">按钮</button>

② 可以通过为对象的指定事件属性设置回调函数的形式来处理事件

<button id="btn">按钮</button>
<script>
	var btn = document.getElementById("btn");
	//绑定一个单击事件
	//像这种为单击事件绑定的函数,我们称为单击响应函数
	btn.onclick = function(){
		alert("你还点~~~");
	};
</script>

3)文档的加载

浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,此时将会无法正常获取到DOM对象,导致DOM操作失败。
        - 解决方式一:
            - 可以将js代码编写到body的下边

            <body>
                <button id="btn">按钮</button>
                <script>
                    var btn = document.getElementById("btn");
                    btn.onclick = function(){
                    
                    };
                </script>
            </body>

        - 解决方式二:
            - 将js代码编写到window.onload = function(){}中
            - window.onload 对应的回调函数会在整个页面加载完毕以后才执行,所以可以确保代码执行时,DOM对象已经加载完毕了

            <script>
                window.onload = function(){
                    var btn = document.getElementById("btn");
                    btn.onclick = function(){
                    
                    };
                };
            
            </script>    

3.16 DOM 查询

    - 通过具体的元素节点来查询
        - 元素.getElementsByTagName()
            - 通过标签名查询当前元素的指定后代元素
            
        - 元素.childNodes
            - 获取当前元素的所有子节点
            - 会获取到空白的文本子节点
        
        - 元素.children
            - 获取当前元素的所有子元素
        
        - 元素.firstChild
            - 获取当前元素的第一个子节点
        
        - 元素.lastChild
            - 获取当前元素的最后一个子节点
        
        - 元素.parentNode
            - 获取当前元素的父元素
        
        - 元素.previousSibling
            - 获取当前元素的前一个兄弟节点
        
        - 元素.nextSibling
            - 获取当前元素的后一个兄弟节点
            
    innerHTML和innerText

        - 这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性
        - 两个属性作用类似,都可以获取到标签内部的内容,
            不同是innerHTML会获取到html标签,而innerText会自动去除标签
        - 如果使用这两个属性来设置标签内部的内容时,没有任何区别的    
        
    读取标签内部的文本内容
        <h1>h1中的文本内容</h1>
        元素.firstChild.nodeValue
        
    - document对象的其他的属性和方法
        document.all
            - 获取页面中的所有元素,相当于document.getElementsByTagName("*");
            
        document.documentElement
            - 获取页面中html根元素
            
        document.body
            - 获取页面中的body元素
            
        document.getElementsByClassName()
            - 根据元素的class属性值查询一组元素节点对象
            - 这个方法不支持IE8及以下的浏览器
            
        document.querySelector()
            - 根据CSS选择器去页面中查询一个元素
            - 如果匹配到的元素有多个,则它会返回查询到的第一个元素    
            
        document.querySelectorAll()    
            - 根据CSS选择器去页面中查询一组元素
            - 会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Untitled Document</title>
		<link rel="stylesheet" type="text/css" href="style/css.css" />
		<script type="text/javascript">
		
			window.onload = function(){
				
				//为id为btn01的按钮绑定一个单击响应函数
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					//查找#bj节点
					var bj = document.getElementById("bj");
					//打印bj
					//innerHTML 通过这个属性可以获取到元素内部的html代码
					alert(bj.innerHTML);
				};
				
				
				//为id为btn02的按钮绑定一个单击响应函数
				var btn02 = document.getElementById("btn02");
				btn02.onclick = function(){
					//查找所有li节点
					//getElementsByTagName()可以根据标签名来获取一组元素节点对象
					//这个方法会给我们返回一个类数组对象,所有查询到的元素都会封装到对象中
					//即使查询到的元素只有一个,也会封装到数组中返回
					var lis = document.getElementsByTagName("li");
					
					//打印lis
					//alert(lis.length);
					
					//变量lis
					for(var i=0 ; i<lis.length ; i++){
						alert(lis[i].innerHTML);
					}
				};
				
				
				//为id为btn03的按钮绑定一个单击响应函数
				var btn03 = document.getElementById("btn03");
				btn03.onclick = function(){
					//查找name=gender的所有节点
					var inputs = document.getElementsByName("gender");
					
					//alert(inputs.length);
					
					for(var i=0 ; i<inputs.length ; i++){
						/*
						 * innerHTML用于获取元素内部的HTML代码的
						 * 	对于自结束标签,这个属性没有意义
						 */
						//alert(inputs[i].innerHTML);
						/*
						 * 如果需要读取元素节点属性,
						 * 	直接使用 元素.属性名
						 * 		例子:元素.id 元素.name 元素.value
						 * 		注意:class属性不能采用这种方式,
						 * 			读取class属性时需要使用 元素.className
						 */
						alert(inputs[i].className);
					}
				};
				
				
				
				//查找#city下所有li节点
				//返回#city的所有子节点
				//返回#phone的第一个子节点
				//返回#bj的父节点
				//返回#android的前一个兄弟节点
				//读取#username的value属性值
				//设置#username的value属性值
				//返回#bj的文本值
				
			};
			
		
		</script>
	</head>
	<body>
		<div id="total">
			<div class="inner">
				<p>
					你喜欢哪个城市?
				</p>

				<ul id="city">
					<li id="bj">北京</li>
					<li>上海</li>
					<li>东京</li>
					<li>首尔</li>
				</ul>

				<br>
				<br>

				<p>
					你喜欢哪款单机游戏?
				</p>

				<ul id="game">
					<li id="rl">红警</li>
					<li>实况</li>
					<li>极品飞车</li>
					<li>魔兽</li>
				</ul>

				<br />
				<br />

				<p>
					你手机的操作系统是?
				</p>

				<ul id="phone"><li>IOS</li><li id="android">Android</li><li>Windows Phone</li></ul>
			</div>

			<div class="inner">
				gender:
				<input class="hello" type="radio" name="gender" value="male"/>
				Male
				<input class="hello" type="radio" name="gender" value="female"/>
				Female
				<br>
				<br>
				name:
				<input type="text" name="name" id="username" value="abcde"/>
			</div>
		</div>
		<div id="btnList">
			<div><button id="btn01">查找#bj节点</button></div>
			<div><button id="btn02">查找所有li节点</button></div>
			<div><button id="btn03">查找name=gender的所有节点</button></div>
			<div><button id="btn04">查找#city下所有li节点</button></div>
			<div><button id="btn05">返回#city的所有子节点</button></div>
			<div><button id="btn06">返回#phone的第一个子节点</button></div>
			<div><button id="btn07">返回#bj的父节点</button></div>
			<div><button id="btn08">返回#android的前一个兄弟节点</button></div>
			<div><button id="btn09">返回#username的value属性值</button></div>
			<div><button id="btn10">设置#username的value属性值</button></div>
			<div><button id="btn11">返回#bj的文本值</button></div>
		</div>
	</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Untitled Document</title>
		<link rel="stylesheet" type="text/css" href="style/css.css" />
		<script type="text/javascript">
		
			/*
			 * 定义一个函数,专门用来为指定元素绑定单击响应函数
			 * 	参数:
			 * 		idStr 要绑定单击响应函数的对象的id属性值
			 * 		fun 事件的回调函数,当单击元素时,该函数将会被触发
			 */
			function myClick(idStr , fun){
				var btn = document.getElementById(idStr);
				btn.onclick = fun;
			}
		
			window.onload = function(){
				
				//为id为btn01的按钮绑定一个单击响应函数
				var btn01 = document.getElementById("btn01");
				btn01.onclick = function(){
					//查找#bj节点
					var bj = document.getElementById("bj");
					//打印bj
					//innerHTML 通过这个属性可以获取到元素内部的html代码
					alert(bj.innerHTML);
				};
				
				
				//为id为btn02的按钮绑定一个单击响应函数
				var btn02 = document.getElementById("btn02");
				btn02.onclick = function(){
					//查找所有li节点
					//getElementsByTagName()可以根据标签名来获取一组元素节点对象
					//这个方法会给我们返回一个类数组对象,所有查询到的元素都会封装到对象中
					//即使查询到的元素只有一个,也会封装到数组中返回
					var lis = document.getElementsByTagName("li");
					
					//打印lis
					//alert(lis.length);
					
					//变量lis
					for(var i=0 ; i<lis.length ; i++){
						alert(lis[i].innerHTML);
					}
				};
				
				
				//为id为btn03的按钮绑定一个单击响应函数
				var btn03 = document.getElementById("btn03");
				btn03.onclick = function(){
					//查找name=gender的所有节点
					var inputs = document.getElementsByName("gender");
					
					//alert(inputs.length);
					
					for(var i=0 ; i<inputs.length ; i++){
						/*
						 * innerHTML用于获取元素内部的HTML代码的
						 * 	对于自结束标签,这个属性没有意义
						 */
						//alert(inputs[i].innerHTML);
						/*
						 * 如果需要读取元素节点属性,
						 * 	直接使用 元素.属性名
						 * 		例子:元素.id 元素.name 元素.value
						 * 		注意:class属性不能采用这种方式,
						 * 			读取class属性时需要使用 元素.className
						 */
						alert(inputs[i].className);
					}
				};
				
				//为id为btn04的按钮绑定一个单击响应函数
				var btn04 = document.getElementById("btn04");
				btn04.onclick = function(){
					
					//获取id为city的元素
					var city = document.getElementById("city");
					
					//查找#city下所有li节点
					var lis = city.getElementsByTagName("li");
					
					for(var i=0 ; i<lis.length ; i++){
						alert(lis[i].innerHTML);
					}
					
				};
				
				//为id为btn05的按钮绑定一个单击响应函数
				var btn05 = document.getElementById("btn05");
				btn05.onclick = function(){
					//获取id为city的节点
					var city = document.getElementById("city");
					//返回#city的所有子节点
					/*
					 * childNodes属性会获取包括文本节点在呢的所有节点
					 * 根据DOM标签标签间空白也会当成文本节点
					 * 注意:在IE8及以下的浏览器中,不会将空白文本当成子节点,
					 * 	所以该属性在IE8中会返回4个子元素而其他浏览器是9个
					 */
					var cns = city.childNodes;
					
					//alert(cns.length);
					
					/*for(var i=0 ; i<cns.length ; i++){
						alert(cns[i]);
					}*/
					
					/*
					 * children属性可以获取当前元素的所有子元素
					 */
					var cns2 = city.children;
					alert(cns2.length);
				};
				
				//为id为btn06的按钮绑定一个单击响应函数
				var btn06 = document.getElementById("btn06");
				btn06.onclick = function(){
					//获取id为phone的元素
					var phone = document.getElementById("phone");
					//返回#phone的第一个子节点
					//phone.childNodes[0];
					//firstChild可以获取到当前元素的第一个子节点(包括空白文本节点)
					var fir = phone.firstChild;
					
					//firstElementChild获取当前元素的第一个子元素
					/*
					 * firstElementChild不支持IE8及以下的浏览器,
					 * 	如果需要兼容他们尽量不要使用
					 */
					//fir = phone.firstElementChild;
					
					alert(fir);
				};
				
				//为id为btn07的按钮绑定一个单击响应函数
				myClick("btn07",function(){
					
					//获取id为bj的节点
					var bj = document.getElementById("bj");
					
					//返回#bj的父节点
					var pn = bj.parentNode;
					
					alert(pn.innerHTML);
					
					/*
					 * innerText
					 * 	- 该属性可以获取到元素内部的文本内容
					 * 	- 它和innerHTML类似,不同的是它会自动将html去除
					 */
					//alert(pn.innerText);
					
					
				});
				
				
				//为id为btn08的按钮绑定一个单击响应函数
				myClick("btn08",function(){
					
					//获取id为android的元素
					var and = document.getElementById("android");
					
					//返回#android的前一个兄弟节点(也可能获取到空白的文本)
					var ps = and.previousSibling;
					
					//previousElementSibling获取前一个兄弟元素,IE8及以下不支持
					//var pe = and.previousElementSibling;
					
					alert(ps);
					
				});
				
				//读取#username的value属性值
				myClick("btn09",function(){
					//获取id为username的元素
					var um = document.getElementById("username");
					//读取um的value属性值
					//文本框的value属性值,就是文本框中填写的内容
					alert(um.value);
				});
				
				
				//设置#username的value属性值
				myClick("btn10",function(){
					//获取id为username的元素
					var um = document.getElementById("username");
					
					um.value = "今天天气真不错~~~";
				});
				
				
				//返回#bj的文本值
				myClick("btn11",function(){
					
					//获取id为bj的元素
					var bj = document.getElementById("bj");
					
					//alert(bj.innerHTML);
					//alert(bj.innerText);
					
					//获取bj中的文本节点
					/*var fc = bj.firstChild;
					alert(fc.nodeValue);*/
					
					alert(bj.firstChild.nodeValue);
					
					
				});
				
			};
			
		
		</script>
	</head>
	<body>
		<div id="total">
			<div class="inner">
				<p>
					你喜欢哪个城市?
				</p>

				<ul id="city">
					<li id="bj">北京</li>
					<li>上海</li>
					<li>东京</li>
					<li>首尔</li>
				</ul>

				<br>
				<br>

				<p>
					你喜欢哪款单机游戏?
				</p>

				<ul id="game">
					<li id="rl">红警</li>
					<li>实况</li>
					<li>极品飞车</li>
					<li>魔兽</li>
				</ul>

				<br />
				<br />

				<p>
					你手机的操作系统是?
				</p>

				<ul id="phone"><li>IOS</li> <li id="android">Android</li><li>Windows Phone</li></ul>
			</div>

			<div class="inner">
				gender:
				<input class="hello" type="radio" name="gender" value="male"/>
				Male
				<input class="hello" type="radio" name="gender" value="female"/>
				Female
				<br>
				<br>
				name:
				<input type="text" name="name" id="username" value="abcde"/>
			</div>
		</div>
		<div id="btnList">
			<div><button id="btn01">查找#bj节点</button></div>
			<div><button id="btn02">查找所有li节点</button></div>
			<div><button id="btn03">查找name=gender的所有节点</button></div>
			<div><button id="btn04">查找#city下所有li节点</button></div>
			<div><button id="btn05">返回#city的所有子节点</button></div>
			<div><button id="btn06">返回#phone的第一个子节点</button></div>
			<div><button id="btn07">返回#bj的父节点</button></div>
			<div><button id="btn08">返回#android的前一个兄弟节点</button></div>
			<div><button id="btn09">返回#username的value属性值</button></div>
			<div><button id="btn10">设置#username的value属性值</button></div>
			<div><button id="btn11">返回#bj的文本值</button></div>
		</div>
	</body>
</html>

全选练习:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>全选练习</title>
<script type="text/javascript">

	window.onload = function(){
		
		//获取四个多选框items
		var items = document.getElementsByName("items");
		//获取全选/全不选的多选框
		var checkedAllBox = document.getElementById("checkedAllBox");
		
		/*
		 * 全选按钮
		 * 	- 点击按钮以后,四个多选框全都被选中
		 */
		
		//1.#checkedAllBtn
		//为id为checkedAllBtn的按钮绑定一个单击响应函数
		var checkedAllBtn = document.getElementById("checkedAllBtn");
		checkedAllBtn.onclick = function(){
			
			//遍历items
			for(var i=0 ; i<items.length ; i++){
				
				//通过多选框的checked属性可以来获取或设置多选框的选中状态
				//alert(items[i].checked);
				
				//设置四个多选框变成选中状态
				items[i].checked = true;
			}
			
			//将全选/全不选设置为选中
			checkedAllBox.checked = true;
			
		};
		
		/*
		 * 全不选按钮
		 * 	- 点击按钮以后,四个多选框都变成没选中的状态
		 */
		//2.#checkedNoBtn
		//为id为checkedNoBtn的按钮绑定一个单击响应函数
		var checkedNoBtn = document.getElementById("checkedNoBtn");
		checkedNoBtn.onclick = function(){
			for(var i=0; i<items.length ; i++){
				//将四个多选框设置为没选中的状态
				items[i].checked = false;
			}
			
			//将全选/全不选设置为不选中
			checkedAllBox.checked = false;
			
		};
		
		/*
		 * 反选按钮
		 * 	- 点击按钮以后,选中的变成没选中,没选中的变成选中
		 */
		//3.#checkedRevBtn
		var checkedRevBtn = document.getElementById("checkedRevBtn");
		checkedRevBtn.onclick = function(){
			
			//将checkedAllBox设置为选中状态
			checkedAllBox.checked = true;
			
			for(var i=0; i<items.length ; i++){
				
				//判断多选框状态
				/*if(items[i].checked){
					//证明多选框已选中,则设置为没选中状态
					items[i].checked = false;
				}else{
					//证明多选框没选中,则设置为选中状态
					items[i].checked = true;
				}*/
				
				items[i].checked = !items[i].checked;
				
				//判断四个多选框是否全选
				//只要有一个没选中则就不是全选
				if(!items[i].checked){
					//一旦进入判断,则证明不是全选状态
					//将checkedAllBox设置为没选中状态
					checkedAllBox.checked = false;
				}
			}
			//在反选时也需要判断四个多选框是否全都选中
			
		};
		
		/*
		 * 提交按钮:
		 * 	- 点击按钮以后,将所有选中的多选框的value属性值弹出
		 */
		//4.#sendBtn
		//为sendBtn绑定单击响应函数
		var sendBtn = document.getElementById("sendBtn");
		sendBtn.onclick = function(){
			//遍历items
			for(var i=0 ; i<items.length ; i++){
				//判断多选框是否选中
				if(items[i].checked){
					alert(items[i].value);
				}
			}
		};
		
		//5.#checkedAllBox
		/*
		 * 全选/全不选 多选框
		 * 	- 当它选中时,其余的也选中,当它取消时其余的也取消
		 * 
		 * 在事件的响应函数中,响应函数是给谁绑定的this就是谁
		 */
		//为checkedAllBox绑定单击响应函数
		checkedAllBox.onclick = function(){
			
			//alert(this === checkedAllBox);
			
			//设置多选框的选中状态
			for(var i=0; i <items.length ; i++){
				items[i].checked = this.checked;
			}
			
		};
		
		//6.items
		/*
		 * 如果四个多选框全都选中,则checkedAllBox也应该选中
		 * 如果四个多选框没都选中,则checkedAllBox也不应该选中
		 */
		
		//为四个多选框分别绑定点击响应函数
		for(var i=0 ; i<items.length ; i++){
			items[i].onclick = function(){
				
				//将checkedAllBox设置为选中状态
				checkedAllBox.checked = true;
				
				for(var j=0 ; j<items.length ; j++){
					//判断四个多选框是否全选
					//只要有一个没选中则就不是全选
					if(!items[j].checked){
						//一旦进入判断,则证明不是全选状态
						//将checkedAllBox设置为没选中状态
						checkedAllBox.checked = false;
						//一旦进入判断,则已经得出结果,不用再继续执行循环
						break;
					}
				}
			};
		}
	};
	
</script>
</head>
<body>

	<form method="post" action="">
		你爱好的运动是?<input type="checkbox" id="checkedAllBox" />全选/全不选 
		
		<br />
		<input type="checkbox" name="items" value="足球" />足球
		<input type="checkbox" name="items" value="篮球" />篮球
		<input type="checkbox" name="items" value="羽毛球" />羽毛球
		<input type="checkbox" name="items" value="乒乓球" />乒乓球
		<br />
		<input type="button" id="checkedAllBtn" value="全 选" />
		<input type="button" id="checkedNoBtn" value="全不选" />
		<input type="button" id="checkedRevBtn" value="反 选" />
		<input type="button" id="sendBtn" value="提 交" />
	</form>
</body>
</html>

dom查询的其他方法:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
			window.onload = function(){
				
				//获取body标签
				//var body = document.getElementsByTagName("body")[0];
				
				/*
				 * 在document中有一个属性body,它保存的是body的引用
				 */
				var body = document.body;
				
				/*
				 * document.documentElement保存的是html根标签
				 */
				var html = document.documentElement;
				
				//console.log(html);
				
				/*
				 * document.all代表页面中所有的元素
				 */
				var all = document.all;
				
				//console.log(all.length);
				
				/*for(var i=0 ; i<all.length ; i++){
					console.log(all[i]);
				}*/
				
				//all = document.getElementsByTagName("*");
				//console.log(all.length);
				
				/*
				 * 根据元素的class属性值查询一组元素节点对象
				 * getElementsByClassName()可以根据class属性值获取一组元素节点对象,
				 * 	但是该方法不支持IE8及以下的浏览器
				 */
				//var box1 = document.getElementsByClassName("box1");
				//console.log(box1.length);
				
				//获取页面中的所有的div
				//var divs = document.getElementsByTagName("div");
				
				//获取class为box1中的所有的div
				//.box1 div
				/*
				 * document.querySelector()
				 * 	- 需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象
				 * 	- 虽然IE8中没有getElementsByClassName()但是可以使用querySelector()代替
				 * 	- 使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
				 */
				var div = document.querySelector(".box1 div");
				
				var box1 = document.querySelector(".box1")
				
				//console.log(div.innerHTML);
				//console.log(box1.innerHTML);
				
				/*
				 * document.querySelectorAll()
				 * 	- 该方法和querySelector()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回
				 * 	- 即使符合条件的元素只有一个,它也会返回数组
				 */
				box1 = document.querySelectorAll(".box1");
				box1 = document.querySelectorAll("#box2");
				console.log(box1);
				
			};
			
		</script>
	</head>
	<body>
		<div id="box2"></div>	
		<div class="box1">
			我是第一个box1	 
			<div>我是box1中的div</div>
		</div>
		<div class="box1">
			<div>我是box1中的div</div>
		</div>
		<div class="box1">
			<div>我是box1中的div</div>
		</div>
		<div class="box1">
			<div>我是box1中的div</div>
		</div>
		
		<div></div>
	</body>
</html>

3.17 DOM 修改

    document.createElement()
        - 可以根据标签名创建一个元素节点对象
        
    document.createTextNode()
        - 可以根据文本内容创建一个文本节点对象
        
    父节点.appendChild(子节点)
        - 向父节点中添加指定的子节点
        
    父节点.insertBefore(新节点,旧节点)
        - 将一个新的节点插入到旧节点的前边
        
    父节点.replaceChild(新节点,旧节点)
        - 使用一个新的节点去替换旧节点
        
    父节点.removeChild(子节点)
        - 删除指定的子节点
        - 推荐方式:子节点.parentNode.removeChild(子节点)

3.18 DOM 对 CSS 的操作

    - 读取和修改内联样式
        - 使用style属性来操作元素的内联样式
        - 读取内联样式:
            语法:元素.style.样式名
            - 例子:
                元素.style.width
                元素.style.height
                - 注意:如果样式名中带有-,则需要将样式名修改为驼峰命名法。将-去掉,然后-后的字母改大写
                - 比如:background-color --> backgroundColor
                        border-width ---> borderWidth
                        
        - 修改内联样式:
            语法:元素.style.样式名 = 样式值
            - 通过style修改的样式都是内联样式,由于内联样式的优先级比较高,
                所以我们通过JS来修改的样式,往往会立即生效,
                但是如果样式中设置了!important,则内联样式将不会生效。
                
    - 读取元素的当前样式
        - 正常浏览器
            - 使用getComputedStyle()
            - 这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式
            - 参数:
                1.要获取样式的元素
                2.可以传递一个伪元素,一般传null
            - 例子:
                获取元素的宽度
                    getComputedStyle(box , null)["width"];
            - 通过该方法读取到样式都是只读的不能修改

        - IE8
            - 使用currentStyle
            - 语法:
                元素.currentStyle.样式名
            - 例子:
                box.currentStyle["width"]
            - 通过这个属性读取到的样式是只读的不能修改

    

    - 其他的样式相关的属性
        注意:以下样式都是只读的
    
        clientHeight
            - 元素的可见高度,指元素的内容区和内边距的高度
        clientWidth
            - 元素的可见宽度,指元素的内容区和内边距的宽度
        offsetHeight
            - 整个元素的高度,包括内容区、内边距、边框
        offfsetWidth
            - 整个元素的宽度,包括内容区、内边距、边框
        offsetParent
            - 当前元素的定位父元素
            - 离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body
        offsetLeft
        offsetTop
            - 当前元素和定位父元素之间的偏移量
            - offsetLeft水平偏移量  offsetTop垂直偏移量
        
        scrollHeight
        scrollWidth
            - 获取元素滚动区域的高度和宽度
        
        scrollTop
        scrollLeft
            - 获取元素垂直和水平滚动条滚动的距离
            
        判断滚动条是否滚动到底
            - 垂直滚动条
                scrollHeight - scrollTop = clientHeight
                
            - 水平滚动    
                scrollWidth - scrollLeft = clientWidth

3.19 事件

    - 事件对象
    - 当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向。。
    - 可以在响应函数中定义一个形参,来使用事件对象,但是在IE8以下浏览器中事件对象没有做完实参传递,而是作为window对象的属性保存。
        - 例子:
            元素.事件 = function(event){
                event = event || window.event;
                
            };
            
            元素.事件 = function(e){
                e = e || event;
                
            };
            
    - 事件的冒泡(Bubble)
    - 事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。
    - 事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消
    - 可以将事件对象的cancelBubble设置为true,即可取消冒泡
        - 例子:
                元素.事件 = function(event){
                    event = event || window.event;
                    event.cancelBubble = true;
                };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值