第二阶段
JavaScript基础语法
-
HTML
:标记语言 -
JavaScript
:编程语言
序言
JavaScript发展历史(JS)
1. 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版,这是世界上第一款比较成熟的网络浏览器,轰动一时。但是这是一款名副其实的浏览器--只能浏览页面,浏览器无法与用户互动,当时解决这个问题有两个办法,一个是采用现有的语言,许它们直接嵌入网页。另一个是发明一种全新的语言。 liveScript ==> javaScript ==> ECMAscript 2. 1995年Sun公司将Oak语言改名为Java,正式向市场推出。Sun公司大肆宣传,许诺这种语言可以"一次编写,到处运 行"(Write Once, Run Anywhere),它看上去很可能成为未来的主宰。 3. 网景公司动了心,决定与Sun公司结成联盟 4. 34岁的系统程序员Brendan Eich登场了。1995年4月,网景公司录用了他,他只用10天时间就把Javascript设计出来了。(多肽语言) 5. (1)借鉴C语言的基本语法; (2)借鉴Java语言的数据类型和内存管理; (3)借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位; (4)借鉴Self语言,使用基于原型(prototype)的继承机制。
JavaScript能干什么
1. 常见的网页效果【表单验证,轮播图。。。】 2. 与H5配合实现游戏【水果忍者: http://www.jq22.com/demo/html5-fruit-ninja/】 3. 实现应用级别的程序【http://naotu.baidu.com】 4. 实现统计效果【http://echarts.baidu.com/examples/】 5. 地理定位等功能【http://lbsyun.baidu.com/jsdemo.htm#i4_5】 6. 在线学编程【https://codecombat.163.com/play/】 7. js可以实现人工智能【面部识别】 8. js可以操作页面的元素 1. 先获取两个输入框的值(盲点) // a). 获取元素 输入框 document.getElementById(): 通过id获取元素 // b). 获取元素 输入框的值 document.getElementById().value 9...
JavaScript的组成
1. ECMASCRIPT: 定义了javascript的语法规范,描述了语言的基本语法和数据类型 2. BOM (Browser Object Model): 浏览器对象模型 3. DOM (Document Object Model): 文档对象模型,通过 DOM 可以操作页面中的元素。比如: 增加个 div,减少个 div,给div 换个位置等
总结: JS 就是通过固定的语法去操作 浏览器 和 标签结构 来实现网页上的各种效果
JavaScript代码的书写位置
-
和
css
一样,我们的js
也可以有多种方式书写在页面上让其生效 -
js
也有多种方式书写,分为 行内式, 内嵌式,外链式
行内式 JS 代码(不推荐)
-
写在标签上的 js 代码需要依靠事件(行为)来触发
<!-- 写在 a 标签的 href 属性上 -->
<a href="javascript:alert('我是一个弹出层');">点击一下试试</a>
<!-- 写在其他元素上 -->
<div onclick="alert('我是一个弹出层')">点一下试试看</div>
<!--
注:onclick 是一个事件(点击事件),当点击元素的时候执行后面的 js 代码
-->
内嵌式 JS 代码
-
内嵌式的 js 代码会在页面打开的时候直接触发
<!-- 在 html 页面书写一个 script 标签,标签内部书写 js 代码 -->
<script type="text/javascript">
alert('我是一个弹出层')
</script>
<!--
注:script 标签可以放在 head 里面也可以放在 body 里面
-->
外链式 JS 代码(推荐)
-
外链式 js 代码只要引入了 html 页面,就会在页面打开的时候直接触发
-
新建一个
.js
后缀的文件,在文件内书写 js 代码,把写好的 js 文件引入 html 页面
// 我是 index.js 文件
alert('我是一个弹出层')
<!-- 我是一个 html 文件 -->
<!-- 通过 script 标签的 src 属性,把写好的 js 文件引入页面 -->
<script src="index.js"></script>
<!-- 一个页面可以引入多个 js 文件 -->
<script src="index1.js"></script>
<script src="index2.js"></script>
<script src="index3.js"></script>
JS 中的注释
单行注释
-
可以直接写两个
/
,也可以按ctrl + /
// 我是一个单行注释
// 下面代码表示在浏览器里面出现一个弹出层
alert('我是一个弹出层')
多行注释
-
可以直接写
/**/
然后在两个星号中间写注释,也可以按shift + alt + a
变量(重点)
变量指的是在程序中保存数据的一个容器
变量是计算机内存中存储数据的标识符,根据变量名称可以获取到内存中存储的数据
语法: `var 变量名 = 值
定义变量及赋值
// 定义一个变量 var num; // 给一个变量赋值 num = 100; // 定义一个变量的同时给其赋值 var num2 = 200;
注意:
一个变量名只能存储一个值
当再次给一个变量赋值的时候,前面一次的值就没有了
变量名称区分大小写(JS 区分大小写)
变量的命名规则和命名规范
-
规则: 必须遵守的,不遵守就是错
-
一个变量名称可以由 数字、字母、英文下划线(_)、美元符号($) 组成
-
严格区分大小写
-
不能由数字开头,不要使用中文汉字命名
-
不能是 保留字 或者 关键字
-
不要出现空格
-
-
规范: 建议遵守的(开发者默认),不遵守不会报错
-
见名识意(语义化)
-
遵循驼峰命名规则,由多个单词组成的时候,从第二个单词开始首字母大写
-
数据类型(重点)
-
是指我们存储在内存中的数据的类型
-
我们通常分为两大类 基本数据类型 和 复杂数据类型
基本数据类型
-
数值类型(number)
-
一切数字都是数值类型(包括二进制,十进制,十六进制等)
-
NaN(not a number),一个非数字
-
-
字符串类型(string)
被引号包裹的所有内容(可以是单引号也可以是双引号) -
布尔类型(boolean)
只有两个(true 或者 false) -
undefined类型(undefined)
只有一个,就是 undefined,表示没有值的意思 -
null类型(null)
只有一个,就是 null,表示空的意思
复杂数据类型(暂时先不讲)
-
对象类型(object)
-
函数类型(function)
-
。。。
判断数据类型
-
使用
typeof
关键字来进行判断
// 第一种使用方式
var n1 = 100;
console.log(typeof n1); // number
// 第二种使用方式
var s1 = 'abcdefg';
console.log(typeof(s1));//string
判断数据类型的注意点
控制台:检测手段(数字类型和字符串类型):看颜色,黑色字符串,蓝色是数字类型 typeof x typeof(x) typeof的返回值是什么(类型的返回值)? 'number' typeof 10 'string' 'x' 'boolean' true 'undefined' 'object'---> null typeof的返回值的类型是什么? 字符串 typeof typeof 'hhah'; 'string'
判断一个变量是不是数字
-
可以使用
isNaN
这个方法来判断一个变量是否为非数字isNaN检测是否为非数字
-
isNaN
:is not a number
isNaN()检测是否为非数字,如果不是数字,返回true,如果是数字,返回false 底层会调用Number() isNaN()等价于isNaN(Number(x)) isNaN('100px')---》true isNaN('100')---》false
// 如果变量是一个数字
var n1 = 100;
console.log(isNaN(n1)); //=> false
// 如果变量不是一个数字
var s1 = 'Jack'
console.log(isNaN(s1)); //=> true
数据类型转换
-
数据类型之间的转换,比如数字转成字符串,字符串转成布尔,布尔转成数字等
其他数据类型转成数值
-
Number(变量)
(只能将纯数字的字符串转为数字类型)
-
可以把一个变量强制转换成数值类型
-
可以转换布尔值,将true转为1,false转为0,转换不成功的是NaN
-
遇到不可转换的都会返回 NaN
-
-
parseInt(变量)
( 将数字开头的字符串转为整数类型)
-
从第一位开始检查,是数字就转换,知道一个不是数字的内容
-
开头就不是数字,那么直接返回 NaN
-
不认识小数点,只能保留整数
-
-
parseFloat(变量)
( 将数字开头的字符串转为小数类型)
-
从第一位开始检查,是数字就转换,知道一个不是数字的内容
-
开头就不是数字,那么直接返回 NaN
-
小数全保留
-
-
除了加法以外的数学运算(隐式转换:正号,-*/%)
-
运算符两边都是可运算数字才行
-
如果运算符任何一边不是一个可运算数字,那么就会返回 NaN
-
加法不可以用
( NaN的出现:转换数字类型,数值类型转换不成功就是NaN)
-
其他数据类型转成字符串
-
变量.toString()
-
有一些数据类型不能使用
toString()
方法,比如 undefined 和 null
-
-
String(变量)
-
所有数据类型都可以
-
-
使用加法运算
-
在 JS 里面,
+
由两个含义 -
字符串拼接: 只要
+
的 任意一边是字符串,就会进行字符串拼接 -
加法运算:只有
+
两边都是数字的时候,才会进行数学运算var x = 10; //number 隐式转换转为字符: console.log(x+'') //10 console.log(''+x) //10 全为数字时进行计算: console.log(10+10+x) //30 字符串的拼接:前有数字,先进行计算再进行拼接 console.log(10+10+""+x); //20+''+10='20'+10=2010 console.log(10+10+""+10+x); //20+""+10+10='20'+10+10='2010'+10='201010'
-
其他数据类型转成布尔
-
Boolean(变量)
-
在 js 中,只有
''
、0
、null
、undefined
、NaN
,这些是 false,其余都是 true
-
运算符
-
就是在代码里面进行运算的时候使用的符号,不光只是数学运算,我们在 js 里面还有很多的运算方式
算术运算符:+ - * / % 赋值运算符: = += -= *= /= %= 比较运算符(关系运算符):> < >= <= == === != 比较的结果是一个布尔类型 !!!注: == 比较值,不比较类型(隐式转换) '1' == 1 '2' < 19(一个数字和一个字符串,在进行比较时,会进行隐式转换)
目录
数学运算符
-
+
-
只有符号两边都是数字类型的时候才会进行加法运算
-
只要符号任意一边是字符串类型,就会进行字符串拼接
-
-
-
* / %-
会执行减法/乘法/除法/除法运算
-
会自动把两边都转换成数字进行运算
-
赋值运算符
-
=
-
就是把
=
右边的赋值给等号左边的变量名 -
var num = 100
-
-
+=
var a = 10; a += 10; console.log(a); //=> 20
-
a += 10
等价于a = a + 10
-
-
-=
var a = 10; a -= 10; console.log(a); //=> 0
-
a -= 10
等价于a = a - 10
-
-
*=
var a = 10; a *= 10; console.log(a); //=> 100
-
a *= 10
等价于a = a * 10
-
-
/+
var a = 10; a /= 10; console.log(a); //=> 1
-
a /= 10
等价于a = a / 10
-
-
%=
var a = 10; a %= 10; console.log(a); //=> 0
-
a %= 10
等价于a = a % 10
-
比较运算符
-
==
-
比较符号两边的值是否相等,不管数据类型
-
1 == '1'
-
两个的值是一样的,所以得到 true
-
-
===
-
比较符号两边的值和数据类型是否都相等
-
1 === '1'
-
两个值虽然一样,但是因为数据类型不一样,所以得到 false
-
-
!=
-
比较符号两边的值是否不等
-
1 != '1'
-
因为两边的值是相等的,所以比较他们不等的时候得到 false
-
-
!==
-
比较符号两边的数据类型和值是否不等
-
1 !== '1'
-
因为两边的数据类型确实不一样,所以得到 true
-
-
>=
-
比较左边的值是否 大于或等于 右边的值
-
1 >= 1
true
-
-
<=
-
比较左边的值是否 小于或等于 右边的值
-
1 <= 0
false
-
-
>
-
比较左边的值是否 大于 右边的值
-
1 > 0
true -
字符串的比较:ASCII表进行,字符,字符对应的码值(数字)
-
-
<
-
比较左边的值是否 小于 右边的值
-
1 < 2
true
-
逻辑运算符
-
&&
-
进行 且 的运算
-
一假即假
-
true && true
true -
true && false
false
-
-
||
-
进行 或 的运算
-
一真即真
-
true || true
true -
false || false
false
-
-
!
当项目的需求表示不出来,但是对立面可以表示出来,就可以用取反.
例如: 求平年,不是闰年就是平年,闰年取反就是平年.
-
进行 取反 运算
-
本身是 true 的,会变成 false
-
本身是 false 的,会变成 true
-
!true
false -
!false
true
-
自增自减运算符(一元运算符)
-
++
-
进行自增运算
-
分成两种,前置++ 和 后置++
-
前置++,会先把值自动 +1,在返回
var a = 10; console.log(++a); // 会返回 11,并且把 a 的值变成 11 ++x 先加1后操作,前加一,加完再进行其他操作.
-
后置++,会先把值返回,在自动+1
var a = 10; console.log(a++); // 会返回 10,然后把 a 的值变成 11 x++ 先操作(运算,赋值,输出)再加1
-
-
--
-
进行自减运算
-
分成两种,前置-- 和 后置--
-
和
++
运算符道理一样
-
流程控制
流程控制
流程控制概念
顺序:根据代码的书写顺序,从上向下一行一行执行
选择:根据条件的真假,选择执行某种响应的结果
表达式:是由数字、运算符、变量等组成的式子
表达式最终都会有一个结果,返回给开发者,称为返回值
简单理解:流程控制就是来控制代码按照一定结构顺序来执行
流程控制主要有三种结构,分别是顺序结构、分支结构和循环结构,代表三种代码执行的顺序。
顺序流程控制
顺序结构是程序中最简单、最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
分支流程控制
-
分支结构
由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果
JS 语言提供了两种分支结构语句:if 语句、switch 语句
-
if 语句
-
语法结构
// 条件成立执行代码,否则什么也不做 if (条件表达式) { // 条件成立执行的代码语句 }
语句可以理解为一个行为,循环语句和分支语句就是典型的语句。一个程序由很多个语句组成,一般情况下,会分割成一个一个的语句。
-
-
if else语句(双分支语句)
-
语法结构
// 条件成立 执行 if 里面代码,否则执行else 里面的代码 if (条件表达式) { // [如果] 条件成立执行的代码 } else { // [否则] 执行的代码 }
-
执行流程
-
-
if else if 语句(多分支语句)
-
语法结构
// 适合于检查多重条件。 if (条件表达式1) { 语句1; } else if (条件表达式2) { 语句2; } else if (条件表达式3) { 语句3; .... } else { // 上述条件都不成立执行此处代码 }
-
执行逻辑
-
分支结构
-
我们的 js 代码都是顺序执行的(从上到下)
-
逻辑分支就是根据我们设定好的条件来决定要不要执行某些代码
if条件分支结构
if 语句
-
通过一个 if 语句来决定代码执行与否
-
语法:
if (条件) { 要执行的代码 }
-
通过
()
里面的条件是否成立来决定{}
里面的代码是否执行// 条件为 true 的时候执行 {} 里面的代码 if (true) { alert('因为条件是 true,我会执行') } // 条件为 false 的时候不执行 {} 里面的代码 if (false) { alert('因为条件是 false,我不会执行') } 注意:if的括号内部隐式调用了Boolan() if(Boolean(x)){ }
if else 语句
-
通过 if 条件来决定,执行哪一个
{}
里面的代码 -
语法:
if (条件) { 条件为 true 的时候执行 } else { 条件为 false 的时候执行 }
-
两个
{}
内的代码一定有一个会执行// 条件为 true 的时候,会执行 if 后面的 {} if (true) { alert('因为条件是 true,我会执行') } else { alert('因为条件是 true,我不会执行') } // 条件为 false 的时候,会执行 else 后面的 {} if (false) { alert('因为条件为 false,我不会执行') } else { alert('因为条件为 false,我会执行') }
if else if ... 语句
-
可以通过 if 和 else if 来设置多个条件进行判断
-
语法:
if (条件1) { 条件1为 true 的时候执行 } else if (条件2) { 条件2为 true 的时候执行 }
-
会从头开始依次判断条件
-
如果第一个条件为 true 了,那么就会执行后面的
{}
里面的内容 -
如果第一个条件为 false,那么就会判断第二个条件,依次类推
-
-
多个
{}
,只会有一个被执行,一旦有一个条件为 true 了,后面的就不在判断了// 第一个条件为 true,第二个条件为 false,最终会打印 “我是代码段1” if (true) { alert('我是代码段1') } else if (false) { alert('我是代码段2') } // 第一个条件为 true,第二个条件为 true,最终会打印 “我是代码段1” // 因为只要前面有一个条件满足了,就不会继续判断了 if (true) { alert('我是代码段1') } else if (true) { alert('我是代码段2') } // 第一个条件为 false,第二个条件为 true,最终会打印 “我是代码段2” // 只有前一个条件为 false 的时候才会继续向后判断 if (false) { alert('我是代码段1') } else if (true) { alert('我是代码段2') } // 第一个条件为 false,第二个条件为 false,最终什么也不会发生 // 因为当所有条件都为 false 的时候,两个 {} 里面的代码都不会执行 if (false) { alert('我是代码段1') } else if (false) { alert('我是代码段2') }
if else if … else 语句
-
和之前的
if else if ...
基本一致,只不过是在所有条件都不满足的时候,执行最后 else 后面的{}
// 第一个条件为 false,第二个条件为 false,最终会打印 “我是代码段3” // 只有前面所有的条件都不满足的时候会执行 else 后面的 {} 里面的代码 // 只要前面有一个条件满足了,那么后面的就都不会执行了 if (false) { alert('我是代码段1') } else if (false) { alert('我是代码段2') } else { alert('我是代码段3') }
SWITCH 条件分支结构
-
也是条件判断语句的一种
switch语句执行效率高于if多分支,if多分支运用场景比switch多
-
是对于某一个变量的判断
-
语法:
switch (要判断的变量) { case 情况1: 情况1要执行的代码 break case 情况2: 情况2要执行的代码 break case 情况3: 情况3要执行的代码 break default: 上述情况都不满足的时候执行的代码 }
-
要判断某一个变量 等于 某一个值得时候使用
-
-
例子🌰: 根据变量给出的数字显示是星期几
var week = 1 switch (week) { case 1: alert('星期一') break case 2: alert('星期二') break case 3: alert('星期三') break case 4: alert('星期四') break case 5: alert('星期五') break case 6: alert('星期六') break case 7: alert('星期日') break default: alert('请输入一个 1 ~ 7 之间的数字') }
三元运算(扩展)
-
三元运算,就是用 两个符号 组成一个语句
-
三元运算只是对 if else 语句的一个简写形式
-
语法:
条件 ? 条件为 true 的时候执行 : 条件为 false 的时候执行
表达式:是一个式子(得到一个值)或者一个值; 三元运算符的结构: // 条件表达式? 表达式1:表达式2 // 条件表达式结果为true,得到表达式1;为false,得到为表达式2 var age = 18; age >= 18 ? alert('已经成年') : alert('没有成年')
打断点
f12-- > sources --> 点到你的页面 --> 打断点 --> 刷新页面 --> step over-->让代码执行下去 // -->离开时关断点 一般循环语句里面,打断点可以监控for循环里重新赋值的变量,在step into next里面检查,循环值的变化
循环结构
-
循环结构,就是根据某些给出的条件,重复的执行同一段代码
-
循环必须要有某些固定的内容组成
-
初始化
-
条件判断
-
要执行的代码
-
自身改变
-
-
循环分为三种:for循环,while循环,do while循环
WHILE 循环
-
while
, 当…时,其实就是当条件满足时就执行代码,一旦不满足了就不执行了 -
语法
while (条件) { 满足条件就执行 }
-
因为满足条件就执行,所以我们写的时候一定要注意,就是设定一个边界值,不然就一直循环下去了
初始化变量; while(条件表达式){ 语句体; 自增自减表达式; } // 1. 初始化条件 var num = 0; // 2. 条件判断 while (num < 10) { // 3. 要执行的代码 console.log('当前的 num 的值是 ' + num) // 4. 自身改变 num = num + 1 }
-
如果没有自身改变,那么就会一直循环不停了
-
DO WHILE 循环
-
是一个和
while
循环类似的循环 -
while
会先进行条件判断,满足就执行,不满足直接就不执行了 -
但是
do while
循环是,先不管条件,先执行一回,然后在开始进行条件判断 -
语法:
do { 要执行的代码 } while (条件)
初始化变量; do{ 循环体; 自增自减表达式 }while(条件表达式); // 下面这个代码,条件一开始就不满足,但是依旧会执行一次 do 后面 {} 内部的代码 var num = 10 do { console.log('我执行了一次') num = num + 1 } while (num < 10)
FOR 循环
-
和
while
和do while
循环都不太一样的一种循环结构 -
道理是和其他两种一样的,都是循环执行代码的
-
语法:
for (var i = 0; i < 10; i++) { 要执行的代码 }
for(初始化语句;条件表达式;自增自减表达式){} 或者 for(初始化语句;条件表达式;操作表达式){} // 把初始化,条件判断,自身改变,写在了一起 for (var i = 1; i <= 10; i++) { // 这里写的是要执行的代码 console.log(i) } // 控制台会依次输出 1 ~ 10
-
这个只是看起来不太舒服,但是用起来比较好用
# 循环嵌套
对于循环嵌套:外层循环控制行数,内层循环控制每行的个数
BREAK 终止循环
-
在循环没有进行完毕的时候,因为我设置的条件满足,提前终止循环
-
比如:我要吃五个包子,吃到三个的时候,不能在吃了,我就停止吃包子这个事情
-
要终止循环,就可以直接使用
break
关键字break :中止当前(本层)循环,不再循环 for (var i = 1; i <= 5; i++) { // 每循环一次,吃一个包子 console.log('我吃了一个包子') // 当 i 的值为 3 的时候,条件为 true,执行 {} 里面的代码终止循环 // 循环就不会继续向下执行了,也就没有 4 和 5 了 if (i === 3) { break } }
CONTINUE 结束本次循环
-
在循环中,把循环的本次跳过去,继续执行后续的循环
-
比如:吃五个包子,到第三个的时候,第三个掉地下了,不吃了,跳过第三个,继续吃第四个和第五个
-
跳过本次循环,就可以使用
continue
关键字continue:中止本次循环,继续下一次循环 for (var i = 1; i <= 5; i++) { // 当 i 的值为 3 的时候,执行 {} 里面的代码 // {} 里面有 continue,那么本次循环后面的代码就都不执行了 // 自动算作 i 为 3 的这一次结束了,去继续执行 i = 4 的那次循环了 if (i === 3) { console.log('这个是第三个包子,掉地下了,我不吃了') continue } console.log('我吃了一个包子') }
函数
函数的概念
函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。
先看一段代码 // eg:以前写的一段代码 for (var i = 0; i < 10; i++) { console.log(i) } // 函数,这个 {} 就是那个 “盒子” function fn() { // 这个函数我们以前写的代码 for (var i = 0; i < 10; i++) { console.log(i) } }
函数的两个阶段(重点)
-
按照我们刚才的说法,两个阶段就是 放在盒子里面 和 让盒子里面的代码执行
函数定义阶段
-
定义阶段就是我们把代码 放在盒子里面
-
我们就要学习怎么 放进去,也就是书写一个函数
-
我们有两种定义方式 声明式 和 赋值式(函数表达式)
函数的声明
// 声明函数 function 函数名() { //函数体代码 }
-
function 是声明函数的关键字,必须小写
-
由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名命名为动词,比如 getSum
代码展示如下
//声明一个名为和helloWord的函数 function helloWord() { console.log('hi~~'); }
赋值式
又称为函数表达式
-
其实就是和我们使用
var
关键字是一个道理了 -
首先使用
var
定义一个变量,把一个函数当作值直接赋值给这个变量就可以了 -
语法:
2. 函数表达式(赋值式) var 函数名 = function(){} var fn = function () { // 一段代码 } // 不需要在 function 后面书写函数的名字了,因为在前面已经有了
函数调用阶段
-
就是让 盒子里面 的代码执行一下
-
让函数执行
-
两种定义函数的方式不同,但是调用函数的方式都以一样的
调用一个函数
// 调用函数 函数名(); // 通过调用函数名来执行函数体代码
-
调用的时候千万不要忘记添加小括号
-
口诀:函数不调用,自己不执行
-
注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。
代码如下
//调用helloWord函数 helloWord();
调用上的区别
-
虽然两种定义方式的调用都是一样的,但是还是有一些区别的
-
声明式函数: 调用可以在 定义之前或者定义之后
// 可以调用 fn() // 声明式函数 function fn() { console.log('我是 fn 函数') } // 可以调用 fn()
-
赋值式函数: 调用只能在 定义之后
// 会报错 fn() // 赋值式函数 var fn = function () { console.log('我是 fn 函数') } // 可以调用 fn()
函数的参数(重点)
-
函数参数语法
形参:函数定义时设置接收调用时传入
实参:函数调用时传入小括号内的真实数据
-
参数分为两种 行参 和 实参(形参是形式参数,实参是实际参数,实参的值会赋值给形参)
// 声明式 function fn(行参写在这里) { // 一段代码 } fn(实参写在这里) // 赋值式函数 var fn = function (行参写在这里) { // 一段代码 } fn(实参写在这里)
行参和实参的作用
参数的作用 : 在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。
函数参数的运用:
// 带参数的函数声明 function 函数名(形参1, 形参2 , 形参3...) { // 可以定义任意多的参数,用逗号分隔 // 函数体 } // 带参数的函数调用 函数名(实参1, 实参2, 实参3...);
1.调用的时候实参值是传递给形参的
2.形参简单理解为:不用声明的变量
3.实参和形参的多个参数之间用逗号(,)分隔
-
函数形参和实参数量不匹配时
注意:在JavaScript中,形参的默认值是undefined。
小结:
-
函数可以带参数也可以不带参数
-
声明函数的时候,函数名括号里面的是形参,形参的默认值为 undefined
-
调用函数的时候,函数名括号里面的是实参
-
多个参数中间用逗号分隔
-
形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配
// 书写一个参数 function fn(num) { // 在函数内部就可以使用 num 这个变量 } var fn1 = function (num) { // 在函数内部就可以使用 num 这个变量 } // 书写两个参数 function fun(num1, num2) { // 在函数内部就可以使用 num1 和 num2 这两个变量 } var fun1 = function (num1, num2) { // 在函数内部就可以使用 num1 和 num2 这两个变量 }
-
行参的值是在函数调用的时候由实参决定的
-
实参
-
在函数调用的时候给行参赋值的(调用函数参数叫实参)
-
也就是说,在调用的时候是给一个实际的内容的
function fn(num) { // 函数内部可以使用 num } // 这个函数的本次调用,书写的实参是 100 // 那么本次调用的时候函数内部的 num 就是 100 fn(100) // 这个函数的本次调用,书写的实参是 200 // 那么本次调用的时候函数内部的 num 就是 200 fn(200)
-
函数内部的行参的值,由函数调用的时候传递的实参决定( 函数调用的过程:实际上就是把实参传递给形参)
-
多个参数的时候,是按照顺序一一对应的
function fn(num1, num2) { // 函数内部可以使用 num1 和 num2 } // 函数本次调用的时候,书写的参数是 100 和 200 // 那么本次调用的时候,函数内部的 num1 就是 100,num2 就是 200 fn(100, 200)
-
参数个数的关系
-
行参比实参少
-
因为是按照顺序一一对应的
-
行参少就会拿不到实参给的值,所以在函数内部就没有办法用到这个值
function fn(num1, num2) { // 函数内部可以使用 num1 和 num2 } // 本次调用的时候,传递了两个实参,100 200 和 300 // 100 对应了 num1,200 对应了 num2,300 没有对应的变量 // 所以在函数内部就没有办法依靠变量来使用 300 这个值 fn(100, 200, 300)
-
-
行参比实参多
-
因为是按照顺序一一对应的
-
所以多出来的行参就是没有值的,就是
undefined
function fn(num1, num2, num3) { // 函数内部可以使用 num1 num2 和 num3 } // 本次调用的时候,传递了两个实参,100 和 200 // 就分别对应了 num1 和 num2 // 而 num3 没有实参和其对应,那么 num3 的值就是 undefined fn(100, 200)
-
函数的return(重点)
-
return 返回的意思,其实就是给函数一个 返回值 和 终断函数
终断函数
-
当开始执行函数以后,函数内部的代码就会从上到下的依次执行
-
必须要等到函数内的代码执行完毕
-
而
return
关键字就是可以在函数中间的位置停掉,让后面的代码不在继续执行function fn() { console.log(1) console.log(2) console.log(3) // 写了 return 以后,后面的 4 和 5 就不会继续执行了 return console.log(4) console.log(5) } // 函数调用 fn()
返回值
函数的返回值
-
return 语句
返回值:函数调用整体代表的数据;函数执行完成后可以通过return语句将指定数据返回 。
// 声明函数 function 函数名(){ ... return 需要返回的值; } // 调用函数 函数名(); // 此时调用函数就可以得到函数体内return 后面的值
1.在使用 return 语句时,函数会停止执行,并返回指定的值
2.如果函数没有 return ,返回的值是 undefined
-
break ,continue ,return 的区别
break :结束当前的循环体(如 for、while)
continue :跳出本次循环,继续执行下次循环(如 for、while)
return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码
函数带了一个叫return的关键字,函数调用完毕之后就是一个值,通过return 将函数的计算结果给带出来 // 比如 1 + 2 是一个表达式,那么 这个表达式的结果就是 3 console.log(1 + 2) // 3 function fn() { // 执行代码 } // fn() 也是一个表达式,这个表达式就没有结果出现 console.log(fn()) // undefined
-
return
关键字就是可以给函数执行完毕一个结果function fn() { // 执行代码 return 100 } // 此时,fn() 这个表达式执行完毕之后就有结果出现了 console.log(fn()) // 100
-
我们可以在函数内部使用
return
关键把任何内容当作这个函数运行后的结果 -
注意: 1.声明的求和和求个数的变量放在for循环的外部 2. return 放在函数的结尾处,不要放在循环内部 3. 函数内部定义的变量,外部访问不到 4. 函数调用的(值)结果就是return 的结果 5. return 终止函数,return语句以后的代码不会被执行 6.如果一个函数没有带return ,默认返回的是undefined
-
函数返回值注意事项
-
return 终止函数
function getSum(num1, num2) { return num1 + num2; // return 后面的代码不会被执行 alert('我是不会被执行的哦!') }
-
return 只能返回一个值
function fn(num1, num2) { return num1, num2; // 返回的结果是最后一个值 }
-
函数如果有return,则返回的是return后面的值;如果函数没有return,则返回undefined
function fun1() { return 666; } console.log(fun1()); // 返回 666 function fun2() { } console.log(fun2()); // 函数返回的结果是 undefined
函数的优点
-
函数就是对一段代码的封装,在我们想调用的时候调用
-
函数的几个优点
-
封装代码,使代码更加简洁
-
复用,在重复功能的时候直接调用就好
-
代码执行时机,随时可以在我们想要执行的时候执行
-
arguments的使用
arguments的使用
当不确定有多少个参数传递的时候,可以用 arguments 来获取。JavaScript 中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
-
具有 length 属性
-
按索引方式储存数据
-
不具有数组的 push , pop 等方法
注意:在函数内部使用该对象,用此对象获取函数调用时传的实参。
代码展示如下
function fn() { for (var i = 0; i < arguments.length; i++) { console.log(arguments[i]); } } fn(1, 2, 3); fn(1, 2, 3, 4, 5);
预解析(重点)
-
预解析 其实就是聊聊 js 代码的编译和执行
-
js 是一个解释型语言,就是在代码执行之前,先对代码进行通读和解释,然后在执行代码
-
也就是说,我们的 js 代码在运行的时候,会经历两个环节 解释代码 和 执行代码
解释代码
-
因为是在所有代码执行之前进行解释,所以叫做 预解析(预解释)
-
需要解释的内容有两个
-
声明式函数
-
在内存中先声明有一个变量名是函数名,并且这个名字代表的内容是一个函数
-
-
var
关键字-
在内存中先声明有一个变量名
-
-
-
看下面一段代码
fn() console.log(num) function fn() { console.log('我是 fn 函数') } var num = 100
-
经过预解析之后可以变形为
function fn() { console.log('我是 fn 函数') } var num fn() console.log(num) num = 100
-
赋值是函数会按照
var
关键字的规则进行预解析函数(下)
作用域(重点)
-
什么是作用域,就是一个变量可以生效的范围
-
变量不是在所有地方都可以使用的,而这个变量的使用范围就是作用域
全局作用域
-
全局作用域是最大的作用域
-
在全局作用域中定义的变量可以在任何地方使用
-
页面打开的时候,浏览器会自动给我们生成一个全局作用域 window
-
这个作用域会一直存在,直到页面关闭就销毁了
// 下面两个变量都是存在在全局作用域下面的,都是可以在任意地方使用的 var num = 100 var num2 = 200
局部作用域
-
局部作用域就是在全局作用域下面有开辟出来的一个相对小一些的作用域
-
在局部作用域中定义的变量只能在这个局部作用域内部使用
-
在 JS 中只有函数能生成一个局部作用域,别的都不行
-
每一个函数,都是一个局部作用域
// 这个 num 是一个全局作用域下的变量 在任何地方都可以使用 var num = 100 function fn() { // 下面这个变量就是一个 fn 局部作用域内部的变量 // 只能在 fn 函数内部使用 var num2 = 200 } fn()
变量的声明提升
js引擎执行代码: 先找到所有声明相关的,进行提升(声明提升) 变量提升和函数提升 变量提升只提升声明部分:var a; 函数提升,提升的是整体: function getSum(){console.log(1+2);} 如果变量提升和函数提升都存在,函数提升会在变量提升的上面 提升到当前作用域的最顶端: //未提升前: console.log(1); console.log(a); getSum(); var a = 10; console.log(2); function getSum(){ console.log(1+2); //提升后 function getSum() { console.log(1 + 2); } var a; console.log(1);//1 console.log(a); //undefined getSum(); // 3 a = 10; console.log(2);//2
变量使用规则(重点)
-
有了作用域以后,变量就有了使用范围,也就有了使用规则
-
变量使用规则分为两种,访问规则 和 赋值规则
访问规则
-
当我想获取一个变量的值的时候,我们管这个行为叫做 访问
-
获取变量的规则:
-
首先,在自己的作用域内部查找,如果有,就直接拿来使用
-
如果没有,就去上一级作用域查找,如果有,就拿来使用
-
如果没有,就继续去上一级作用域查找,依次类推
-
如果一直到全局作用域都没有这个变量,那么就会直接报错(该变量 is not defined)
var num = 100 function fn() { var num2 = 200 function fun() { var num3 = 300 console.log(num3) // 自己作用域内有,拿过来用 console.log(num2) // 自己作用域内没有,就去上一级,就是 fn 的作用域里面找,发现有,拿过来用 console.log(num) // 自己这没有,去上一级 fn 那里也没有,再上一级到全局作用域,发现有,直接用 console.log(a) // 自己没有,一级一级找上去到全局都没有,就会报错 } fun() } fn()
-
-
变量的访问规则 也叫做 作用域的查找机制
-
作用域的查找机制只能是向上找,不能向下找
function fn() { var num = 100 } fn() console.log(num) // 发现自己作用域没有,自己就是全局作用域,没有再上一级了,直接报错
赋值规则
-
当你想给一个变量赋值的时候,那么就先要找到这个变量,在给他赋值
-
变量赋值规则:
-
先在自己作用域内部查找,有就直接赋值
-
没有就去上一级作用域内部查找,有就直接赋值
-
在没有再去上一级作用域查找,有就直接赋值
-
如果一直找到全局作用域都没有,那么就把这个变量定义为全局变量,在给他赋值
function fn() { num = 100 } fn() // fn 调用以后,要给 num 赋值 // 查看自己的作用域内部没有 num 变量 // 就会向上一级查找 // 上一级就是全局作用域,发现依旧没有 // 那么就会把 num 定义为全局的变量,并为其赋值 // 所以 fn() 以后,全局就有了一个变量叫做 num 并且值是 100 console.log(num) // 100
-
递归函数
-
什么是递归函数
-
在编程世界里面,递归就是一个自己调用自己的手段
-
递归函数: 一个函数内部,调用了自己,循环往复
// 下面这个代码就是一个最简单的递归函数 // 在函数内部调用了自己,函数一执行,就调用自己一次,在调用再执行,循环往复,没有止尽 function fn() { fn() } fn()
-
其实递归函数和循环很类似
-
需要有初始化,自增,执行代码,条件判断的,不然就是一个没有尽头的递归函数,我们叫做 死递归
简单实现一个递归
-
我们先在用递归函数简单实现一个效果
-
需求: 求 1 至 5 的和
-
先算 1 + 2 得 3
-
再算 3 + 3 得 6
-
再算 6 + 4 得 10
-
再算 10 + 5 得 15
-
结束
-
-
开始书写,写递归函数先要写结束条件(为了避免出现 “死递归”)
function add(n) { // 传递进来的是 1 // 当 n === 5 的时候要结束 if (n === 5) { return 5 } } add(1)
-
再写不满足条件的时候我们的递归处理
function add(n) { // 传递进来的是 1 // 当 n === 5 的时候要结束 if (n === 5) { return 5 } else { // 不满足条件的时候,就是当前数字 + 比自己大 1 的数字 return n + add(n + 1) } } add(1)
简单了解对象
-
对象是一个复杂数据类型
-
其实说是复杂,但是没有很复杂,只不过是存储了一些基本数据类型的一个集合
var obj = { num: 100, str: 'hello world', boo: true}
-
这里的
{}
和函数中的{}
不一样 -
函数里面的是写代码的,而对象里面是写一些数据的
-
对象就是一个键值对的集合
-
{}
里面的每一个键都是一个成员 -
也就是说,我们可以把一些数据放在一个对象里面,那么他们就互不干扰了
-
其实就是我们准备一个房子,把我们想要的数据放进去,然后把房子的地址给到变量名,当我们需要某一个数据的时候,就可以根据变量名里面存储的地址找到对应的房子,然后去房子里面找到对应的数据
创建一个对象
-
字面量的方式创建一个对象
// 创建一个空对象var obj = {}// 像对象中添加成员obj.name = 'Jack'obj.age = 18
-
内置构造函数的方式创建对象
// 创建一个空对象var obj = new Object()// 向对象中添加成员obj.name = 'Rose'obj.age = 20
-
Object 是 js 内置给我们的构造函数,用于创建一个对象使用的
-
数组
数组的概念
一个变量只能存储一个数据,如果我们有一组数据,比如1到100一百个数字,定义100个变量来存储就太痛苦了,这时候我们就需要数组来存储这样的数据。数组:存储一组数据.
数组的定义
数组为引用类型,创建时可通过构造方法创建。
堆和栈及索引思维
构造方法
1.无参构造函数,创建一空数组
var a1=new Array();
2.一个数字参数构造函数,指定数组长度(由于数组长度可以动态调整,作用并不大),创建指定长度的数组
var a2=new Array(5);
3.带有初始化数据的构造函数,创建数组并初始化参数数据
var a3=new Array(4,'hello',2.34);
数组的定义 1.构造方法 new:在堆内开辟空间的关键词 Array:数组数据类型 var arr=new Array(1,2,3,4,5,6);
字面量
4.使用方括号,创建空数组,等同于调用无参构造函数
var a4=[];
5.使用中括号,并传入初始化数据,等同于调用调用带有初始化数据的构造函数
var a5=[10];
var arr=[1,2,3,4,5,6,7,8,9]; 最常用的
数据类型分类
内置基本类型: Number String Boolean undefined null 引用类型: object 内置类型与引用类型的区别: 内置类型:只有一块空间,在栈区,该空间直接保存着变量的数值 引用类型: 有两块空间,一块栈空间,存储new出来堆空间的地址, 另一块堆空间,存储真正的数值
数组元素的访问
数组名[下标]; 下标:索引,从零开始连续的自然数,基于0; 下标也可以是变量 数组下标的取值范围0~元素个数-1; 数组的长度:length 注意事项: 数组的下标不能越界访问 超出范围出现undefined,不报错, 数组的长度 length console.log(arr.length); 数组的遍历
var arr=[7,8,9,6,5,0,1,2,3]; for(var i=0;i<arr.length;i++){ document.write(arr3[i]+" "); }
数组的逆序: 思想:相当于第一个和最后一个交换,第二个和倒数第二个交换,交换的次数为数组元素个数的一半 交换需要中间变量 程序=算法+语法 算法:先用中文描述出来问题解决的步骤,然后再翻译为JS语言
var t=0;//定义中间变量 var arr=[7,8,9,6,5,1,2,3]; for(var i=0;i<arr.length/2;i++){ t=arr[i]; arr[i]=arr[arr.length-1-i]; arr[arr.length-1-i]=t; } document.write(arr+" ");
分析:7和3交换 规律:arr4[0]和arr4[arr4.length-1-0]交换 以此类推
数组的相关函数
函数需要注意的几个点:功能 ,参数 ,返回值 eg: 封装闰年问题
function getRn(x){ if(x%4==0&&x%100!=0 ||x%400==0){ return true; }else{ return false; } } if(getRn(2008)==true){ console.log('闰年'); }else{ console.log('平年'); }
-
push尾插 (尾插有参返新长)
功能:末尾插入一个或多个元素 参数:push(x1,[x2,x3])必须要有一个参数,方括号里面表示可选的参数,可有可没有. 返回值:返回尾插后新数组的长度
var arr=[1,2,3]; var len=arr.push(4,5,6); console.log(len);//6 console.log(arr);//[1,2,3,4,5,6]
-
pop尾删
pop:尾删 参数:无 返回值:返回被删掉的元素
var arr=[4,5,7,8,5,1,2,3]; var x=arr.pop(); console.log(x,arr);//3,[4,5,7,8,5,1,2]
-
unshift头插 (头插有参返新长)
unshift:头插 功能:头部插入一个或若个元素 参数:unshift(x1,[x2,x3]) 返回值:返回头插后新数组的长度
var arr=[1,2,3]; var x=arr.unshift(4,5,6); console.log(x,arr);//6,[4,5,6,1,2,3]
-
shift 头删
shift:头删 功能:删除第一个元素 参数:无参 返回值:返回被删除的元素
var arr=[1,2,3]; var x=arr.shift(); console.log(x,arr);//1,[2,3]
-
reverse 逆序
reverse 功能:逆序 参数:无 返回值:无 直接改变原数组对象
var arr=[1,2,3,4,5,6]; arr.reverse(); console.log(arr);//[6,5,4,3,2,1]
-
splice 删除指定元素且用新的元素代替
功能:删除指定元素且用新的元素代替 参数:splice(起始位置,偏移量,[替换的元素]); 返回值:被删除的元素(其实就是一个数组) 注意:起始位置:看的下标,偏移量从下标开始算
var arr=[1,2,3,4,5,6]; var arr1=arr.splice(2,3,7,8,9); console.log(arr,arr1);//[1,2,7,8,9,6][3,4,5]
-
concat:拼接数组
功能:拼接数组 参数:concat(数组) 返回值:被拼接的新数组
var arr1=[7,8,9,5,4]; var arr2=[1,2,3,6]; var arr3=arr1.concat(arr2); console.log(arr3);//[7,8,9,5,4,1,2,3,6]
-
join 将数组转换为字符串
功能:将数组转换为字符串 参数:([字符串分隔符]),默认分隔符为逗号 返回值:被分隔的字符串
var arr=[1,2,3,4,5,6]; var arr1=arr.join('*'); console.log(arr1);// 1*2*3*4*5*6
-
-
slice 数组元素的截取
slice 功能:数组元素的截取 参数:slice(起始位置,结束位置);[左闭右开) 返回值:返回被截取的数组
var arr=[1,2,3,4,5,6]; var arr1=arr.slice(2,5); console.log(arr1);// [3,4,5]返回被截取的数组
-
sort(了解)
var arr=[7,8,9,5,1,2,3]; arr.sort(); console.log(arr);// [1, 2, 3, 5, 7, 8, 9]按照字符串的大小排序,内部Ascall码值比较
从小到大
-
多维数组
多维数组 js中多维数组是模拟一维数组的 多维数组实际是一维数组的嵌套
var arr=[ [1,2,3],//arr[0]第一个元素 [4,5],//arr[1]第二个元素 [7,8,9]//arr[2]第三个元素 ] //二维数组的遍历 for(var i=0;i<arr.length;i++){ for(var j=0;j<arr[i].length;j++){ document.write(arri+" "); } document.write(" ") }
// 冒泡排序:两两比较,每趟找出最大或者最小的一个数值 // 趟数:N-1 // 次数:N-1-i
var arr=[5,6,7,4,8,3,9,2,0,1]; var t; for(var i=0;i<arr.length-1;i++){ for(var j=0;j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){ t=arr[j]; arr[j]=arr[j+1]; arr[j+1]=t;//实现交换 } } } console.log(arr);
/* 5,6,7,4,8,3,9,2,0,1 初始数据 模拟第0趟比较 交换9次 5,6,7,4,8,3,9,2,0,1 5,6,7,4,8,3,9,2,0,1 5,6,4,7,8,3,9,2,0,1 5,6,4,7,8,3,9,2,0,1 5,6,4,7,3,8,9,2,0,1 5,6,4,7,3,8,9,2,0,1 5,6,4,7,3,8,2,9,0,1 5,6,4,7,3,8,2,0,9,1 5,6,4,7,3,8,2,0,1, 9 第1趟交换 交换8次 */
选择排序 var arr=[7,8,6,2,10,3]; // 核心:外层循环N-1次 // 内层:循环N-1-i次 // 思路:i控制指定位置 // k控制目标位置 // k=i;用k来查找目标位置 // 最后交换arr[k]和arr[i]; // 每趟交换一次,找到最大(最小)的数,然后放到目标位置,进行下标交换;
var t,k; for(var i=0;i<arr.length-1;i++){//趟数 k=i; //控制目标位置 for(var j=i+1;j<arr.length;j++){//次数 if(arr[k]>arr[j]){ k=j; //下标交换,相当于找到目标位置,与指定位置交换下标 } }t=arr[i]; arr[i]=arr[k]; arr[k]=t; }console.log(arr);
-
-
-
json对象
json数据格式:可用来描述复杂的对象,将多个繁琐的属性或方法封装成一个整体 a.定义:json是由若干个键值对构成的,若干个键值对用逗号分开 且键值对可以包含属性或者方法 var stu={ key1:value1, key2:value2, ... keyN:valueN, } 注意事项:key全部用双引号引起来(不引也不报错); var stu={ "name":"信息工程", "age":200, "id":123 }
json对象属性的使用
json对象属性的使用 方法1:对象名.属性名 console.log(stu.name,stu.age,stu.gender); 1.打点 console.log(stu.age); console.log(stu.id); console.log(stu.name); 方法2:下标法 对象名["索引"],索引相当于下标 var str="id"; console.log(stu["name"],stu["age"],stu[str]); console.log(stu["name"]); console.log(stu["age"]); console.log(stu["id"]); 注意:下标不是变量则写""; 3.json的遍历; for(var 索引变量名 in 容器){ 循环体 } for(var index in stu){ // for...in不支持打点的方式访问value console.log(stu[index]); console.log(stu.index); } var arr=[7,8,6,3,2,1,23]; for (var index in arr){ console.log(index); } 索引下标 4.添加对象自定义属性 对象名.新的属性=数值; var stu={ "name":"信息工程", "age":200, "id":123 } stu.name='写写画画';//key值存在则被修改 console.log(stu.name); stu.gender='M'; console.log(stu.gender);//key值不存在则为添加 5.添加方法的json对象 var stu={ "name":"乐乐", "age":6, "eat":function(){ console.log("eat"); }, "showValue":function(){ // 如果某个成员方法要使用其成员属性或方法 // 必须加this前缀(this目前代表调用该函数的对象本身) console.log(this.name,this.age); this.eat(); } } console.log(stu.name,stu.age); stu.eat(); stu.showValue(); var stu={ "name":"高明",//var name="高明"; "age":18, "eat":function(){ //如果json对象的函数中需要使用其他属性或者函数 // 需要加前缀this // this代表调用该函数的对象本身 console.log(this.name,this.age,this.id); this.eat(); } }
严格模式
严格模式:无法使用未被声明(定义)的变量,但是不限制声明顺序 eg: "use strict"; a=1233; console.log(a); 这样使用会报错 "use strict"; a=1233; console.log(a); var a; 这样使用正确
数组ES5新增方法
-
indexOf
功能:查找目标元素,找到返回下标,找不到返回-1 参数:indexof(目标元素); 返回值:找到返回下标,找不到返回-1 注意事项:若出现重复的元素,则只能查找第一个出现的元素下标 var arr=[7,8,6,3,2,0] console.log(arr.indexOf(4));//-1,没有 案例:数组去重: 数组去重
var arr=[4,5,3,2,3,5,8,7,4,3]; var arr1=[]; for(var i=0;i<arr.length;i++){ if(arr1.indexOf(arr[i])==-1){ arr1.push((arr[i])); } }console.log(arr1);
-
forEash
功能:对数组的所有元素执行某种相同的操作 参数:forEash(回调函数) 回调函数参数:回调函数(数组元素的值,[下标,元素所在的数组]) 返回值:无
var arr=[1,2,3]; function fun(x,index,a){ a[index]+=10; } arr.forEach(fun); console.log(arr); //[11,12,13]
-
map:
功能:和forEash基本一模一样,多一个返回值 参数:map(回调函数) 回调函数参数:回调函数(数组元素的值,[下标,元素所在的数组]) 返回值:用回调函数return的数据,构成一个数组
var arr=[1,2,3]; function fun(x,index,a){ a[index]+=10; return a[index]; } var arr1=arr.map(fun); console.log(arr1); //[11,12,13]
-
filter
功能:按条件过滤元素 参数:filter(回调函数) 回调函数参数:回调函数(数组元素的值,[下标,元素所在的数组]) 返回值:根据当前回调函数return的布尔值,决定是否返回当前元素本身
var arr=[4,5,6,2,1,2,3]; function fun(x){ if(x%2==1){ return true; }else{ return false; } } var arr1=arr.filter(fun); console.log(arr1); //[5,1,3]过滤偶数
回调函数
回调函数:一个被当做参数的函数(函数调用函数) 解决问题:将自定义模块传入至第三方模块 function f1(f){//第三方代码,闭园代码 // f==f2; // f()==f2() f();//这一步是第三方调用的,和自定义模块设计无关 } var f2=function(){ //自定义模块 console.log("f2"); } f1(f2);//函数的调用 //f2
字符串
字符串的定义和创建
1.字面量 var str="heihei"//内置基本类型 console.log(typeof str); console.log(str); 2.构造方法 var str1=new String("heihei");//引用类型 console.log(typeof str1);//object console.log(str1); 结论:一般用字面量方式定义字符串
字符串的应用
ASCII码表 必须记住 97 a 65 A 48 '0' 32 空格 13 回车 注意事项:ascll码值和字符是完全等价的
字符串常见API
-
charAt
charAt 功能:查询索引对应的字符,返回字符 参数:charAt(索引) 返回值:返回索引对应的字符 var str ="adfghjk"; console.log(str.charAt(1));//d console.log(str[0]);//不建议这样写 a
-
charCodeAt
charCodeAt 功能:查询索引对应的字符,返回字符所对应的ASCLL码值 参数:charCodeAt(索引) 返回值:返回索引所对应的ASCLL码值 var str ="adfghjk"; console.log(str.charCodeAt(1));//100
-
length
var str ="adfghjk"; console.log(str.length); //7
案例: 输入字符串,统计字符串有多少个大写字母,小写字母,数字,空格,其他字符
var str = "12a45b cA AB+#$%^"; var bigChar=0; var smallChar=0; var num=0; var space=0; var other=0; for(var i=0;i<str.length;i++){ if(str.charAt(i)>'0'&&str.charAt(i)<='9'){ num++; }else if(str.charAt(i)>'a'&&str.charAt(i)<='z'){ smallChar++; }else if(str.charAt(i)>'A'&&str.charAt(i)<='Z'){ bigChar++; }else if(str.charAt(i)==' '){ space++; }else{ other++; } } console.log(num,smallChar,bigChar,other,space);//4 2 1 8 2
将ascll码值转换为字符串,返回被转换的字符 注意事项:通过String类型名来调用
将ascll码值转换为字符串,返回被转换的字符 注意事项:通过String类型名来调用 fromCharCode(asc1,[asc2,...]); console.log(String.fromCharCode(97,98)); indexOf("abc")查找字符串第一次出现的位置,返回字符串首字母的下标 var str="helloword"; console.log(str.indexOf("l"));//2 lastIndexOf("abc")查找字符串最后一次出现的位置 如果没有 返回-1 var str="helloword"; console.log(str.lastIndexf("l"));//3
-
replace
功能:用参数2替换参数1 参数:replace(参数1,参数2) 返回值:被替换的字符串 只替换第一次出现的一个
var str = "jinyan de ge bi zhu zhe jinyan"; str=str.replace("jinyan","laowang"); console.log(str); //laowang de ge bi zhu zhe jinyan
-
slice
字符串的截取 slice(起始位置,结束位置);左闭右开 substring(起始位置,结束为止);左闭右开
var str = "helloworld"; console.log(str.slice(2,5));//llo console.log(str.substring(2,5));//ll0
slice与substring区别 slice支持负数 var str = "helloworld"; console.log(str.slice(-5,-2));//wor 左开右闭
-
split
功能:字符串分隔符,将字符串转为数组 参数:split("分割字符串") 返回值:新的数组
// 从字符串shi分割开 var str = "cao bo yong shi cao bo lin de di di"; var arr=str.split('shi'); console.log(arr); // ['cao bo yong ', ' cao bo lin de di di']
-
转大小写
转小写 console.log('htiVBNM'.toLowerCase()); //htivbnm 转大写 console.log('htiVBNM'.toUpperCase()); // HTIVBNM
Math and Date 定时器
1.数学对象
数学对象 : 特点不需要定义对象实例,直接通过 Math.方法名 直接调用。
Math.方法名 直接调用
1. Math.floor(小数) 向下取整 取出小于该数的最大整数
Math.floor(4.3);// 4 Math.floor(-4.3);// -5 console.log(Math.floor(4.9));//4 与四舍五入无关
2.Math.ceil(小数) // 向上取整 取出大于该数的最小整数 console.log(Math.ceil(4.3)); //5 console.log(Math.ceil(-4.3)); // -4 3.Math.round(小数) 四舍五入 console.log(Math.round(4.1)); 4. Math.sqrt(number) 开平方根 5. Math.pow(m,n) 返回m的n次方 6. Math.min(1,-2,3,4) 取多个数最小值 7. Math.abs(number) 返回绝对值 8. Math.random() 返回0~1之间的随机数
获取任意区间值的随机函数
for(var i=0; i<50; i++){ //console.log(parseInt(Math.random()*100)%6+3);//[1,6] [2,8] //console.log(Math.round(Math.random() * 6) + 2); //[0,5] [2,8]==[min,max] console.log(rand(100,500)); } function rand(min,max){ return Math.round(Math.random() * (max-min)) + min; }
日期对象
定义: var d = new Date(); 获取时间的方法: getFullYear() //返回年份 getMonth() //返回月份值 ,从0开始 0~11 getDate() //返回日期 getDay() //返回星期几(为数字) 0~6 星期日为0 getHours() //返回小时数 getMinutes() //返回分钟数 getSeconds() //返回秒数
封装时间字符串:
function dateToString(d){ var a = ["星期天","星期一","星期二","星期三","星期四","星期五","星期六",]; var _y = d.getFullYear(); var _m = d.getMonth()+1; var _d = d.getDate(); var _h = toTwo(d.getHours()); var _mm = toTwo(d.getMinutes()); var _s = toTwo(d.getSeconds()); var _w = d.getDay(); var str = _y + "年" + _m + "月" + _d + "日"; str += _h + "时" + _mm + "分" + _s + "秒" + " " + a[d.getDay()]; return str; } function toTwo(v){ return v<10?"0"+v:v; } document.write(dateToString(new Date())); console.log(d.toLocaleString()); //根据本地时间格式,把 Date 对象的日期部分转换为字符串。
字符串改为时间: 方法1: var str = "2001-8-6,18:23:56"; var bir = new Date(str); document.write(bir.getMinutes()); 方法2: Date.parse(日期字符串) //返回自1970年1月1日起至参数日期的毫秒数 var t = new Date(Date.parse(str)); document.write(t.getHours());
设置时间
setDate() //改变Date对象的日期 setHours() //改变小时数 setMinutes() //改变分钟数 setMonth() //改变月份,从0开始 setSeconds() //改变秒数 setTime() //改变完整的时间,毫秒数 setYear() //改变年份
日期差
求两个日期的差,就是计算两个日期之间差多少天。 1,先取得两个日期的时间戳 2,计算时间戳之间的差值 3,将时间戳之间的差值算成天 getTime() //返回完整的时间 ,毫秒数 var d1 = new Date(); var d2 = new Date("1988-6-26"); var x = d1.getTime() - d2.getTime();//毫秒 document.write(x/1000/60/60/24);
定时器
循环定时器: setInterval(函数,执行的间隔/毫秒); //连续执行 三种用法: 1. setInterval(function(){console.log(1);},1000); function fun(){ console.log(1); }
2. setInterval(fun,1000);
3. setInterval("fun()",1000); //不常用 在函数调用的时候,一般来说,"都有"(有双引号有括号),或者"都无"(无双引号无括号) 停止:clearInterval(定时器对象); //清除定时器 var i = 0; function fun(){ console.log(i++); if(i==5){ clearInterval(t); } } t = setInterval(fun,1000);
延迟定时器: setTimeout(回调函数,毫秒数) 设置在指定的毫秒数后执行一次回调函数,返回定时器编号 体现的是延迟完成一件事情。 var t = setTimeout(function(){ document.write("hello lao wang"); },5000); clearTimeout(t); //清除定时器
动态时间
<p id="time">时间</p> var p = document.getElementById("time"); setInterval(function(){ p.innerHTML = new Date(); },1000);
BOM
Broswer Object Model 浏览器对象模型 所有属性及其方法在使用时都应该有前缀 window是所有对象的祖宗 但是window可以省略
window对象常用的属性和方法
三个弹出框:特点阻塞代码执行:所以后面的代码会被阻塞 alert("内容") 弹出框 confirm("提示信息") 确认框 确定返回true 取消返回false prompt("提示信息","默认值") 输入框 返回数值为字符串 所有全局变量都是window对象的属性 所有全局函数都是window对象的方法
两个定时器
setInterval(执行任务,间隔时间): 连续执行定时器 clearInterval setInterval(fn,时间间隔):返回的是该定时器的钥匙,clearInterval(钥匙) setTimeout(执行任务,间隔时间): 用法同上 只执行一次 延时性 clearTimeout() 停止定时器(一般用的不太多) setTimeout(fn,时间间隔):返回的是该定时器的钥匙,clearTimeout(钥匙) 延时定时器
案例:延迟关闭
<html> <head> <meta charset="utf-8" /> <title></title> <style> #box{ width: 200px; height: 200px; background-color: aqua; } </style> </head> <body> <input type="button" value="开始" id="begin"> <input type="button" value="停止" id="end"></br> <div id="box"></div> </body> </html> <script> var d = document.getElementById("box"); var b = document.getElementById("begin"); var e = document.getElementById("end"); var t = null;//注意全局变量定时器的作用域 b.onclick = function(){ t = setTimeout(function(){ d.style.display = "none"; },3000); } e.onclick = function(){ clearTimeout(t); } </script>
延迟加载onload
onload事件:onload 事件会在页面或图像加载完成后立即发生。 window.onload = function(){ console.log("页面加载完成"); } console.log("页面正在加载"); 为了解决三个弹出框的阻塞行为,可以利用延迟加载事件 延迟加载事件:当整个网页全部加载完毕后再执行该函数体 如果不添加延迟加载事件,则script必须写在页面最后,代码执行从上到下,会出现undefined window.οnlοad=function(){ var oP=document.getElementById("test"); console.log(oP.innerHTML); }
location
console.log(location); href:地址属性,可读可写
读: console.log(location.href); //读取地址
写: location.href="小游戏,4399小游戏,小游戏大全,双人小游戏大全 - www.4399.com"; //同样跳转 location.replace("小游戏,4399小游戏,小游戏大全,双人小游戏大全 - www.4399.com");//网站跳转到4399网址界面 覆盖原先网页 没有浏览痕迹
location.reload(); //页面刷新 一般不用
history
history对象包含用户(在浏览器窗口中)访问过的 URL。
方法 :(打点 )
back() 加载 history 列表中的前一个 URL。
forward() 加载 history 列表中的下一个 URL。
go() 加载 history 列表中的某个具体页面,或者要求浏览器移动到指定的页面数量(负数为后退,正数为前进)
-
节点的遍历
节点的遍历
document.body
var str=document.body.firstElementChild.nextElementSibling.firstElementChild.nextElementSibling.innerHTML;
console.log(str); // 2
node Type返回当前节点的类型,返回值判断 元素节点:1(返回值) 文本节点:3
document文档对象
每个载入浏览器的 HTML 文档都会成为 Document 对象。 document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问 document 对象是 window 对象的一部分,可通过 window.document 属性对其进行访问 1.document.write():特点,拥有字符串解析 2.特点:当参与事件时,会覆盖原网页
作用: 找对象 1.document.getElementById("id名");返回对拥有指定 id 的第一个对象的引用。 2.document.getElementsByTagName("标签名");返回带有指定标签名的对象集合,数组。 3.document.getElementsByName("name名");返回带有指定名称的对象集合。 4.document.getElementsByClassName("类名"); 通过类名返回,返回数组; 5.document.querySelector("选择器");通过选择器返回,获取单个ID,类,标签 6.document.querySelectorAll("选择器");获取类,标签批量元素,返回数组
DOM
DOM(Document Object Model),文档对象模型。
节点和节点的关系
根据层次关系访问节点: (包括文本和元素) parentNode 返回节点的父节点 childNodes 返回子节点集合,数组名[i]访问子节点 nextSibling 下一个节点 previousSibling 上一个节点
通过层级关系访问元素节点
firstElementChild 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 lastElementChild 返回节点的最后一个子节点 nextElementSibling 下一个节点 previousElementSibling 上一个节点 parentNode 返回节点的父节点 childNodes 返回子节点集合,数组名[i]访问子节点 eg: var str = a.firstElementChild.innerHTML;
节点类型
节点类型: 通过nodeType属性来判断节点类型 1代表元素节点 3代表文本节点<p id = "_p">123</p> var p = document.getElementById("_p"); //元素类型 1 document.write(p.nodeType); //文本类型 document.write(p.firstChild.nodeType);//3 //属性节点 document.write(p.getAttributeNode("id").nodeType);//2
节点操作
(DOM是树形结构,增加需要生成元素,然后连接元素建立关系) 增加节点:需要两个步骤 a.创建元素 b.追加元素document.createElement(HTML标签名) //创建一个元素节点 node.appendChild(newChild) //newChild 被添加到孩子列表中的末端。 node.insertBefore(newChild, referenceNode) // 将 newChild 节点插入到 referenceNode 之前。 node.removeChild(oldChild) //删除 oldChild子节点。 var oH1=document.createElement("h1");//创建h1元素 oH1.innerHTML="爱高";//给创建的元素赋值 //追加 document.body.appendChild(oH1);
-
创建节点
1.先创建 2.再连接
var oH2 = document.createElement("h2"); oH2.innerHTML = "静夜思"; //连接 document.body.appendChild(oH2); var oP1 = document.createElement("p"); oP1.innerHTML = "床前明月光,"; document.body.appendChild(oP1);
删除节点: 节点.remove(无参) 直接删除 以后这个用的更多一些 list.lastElementChild.remove();
childNodes和children
childNodes返回的是所有的孩子节点,但是实际孩子节点的长度并不是我们想要的那样,因为里面包括了文本元素
针对这种情况,我们需要过滤空白节点:
childNodes:批量获取父元素的子元素,存储在至数组中(返回元素和文本节点) children:批量获取父元素的子元素,存储在数组中(只返回元素节点) 过滤文本节点:
for(var i=0; i<a.length; i++){ //删除空白节点
//如果节点为空白节点,则根据nodeType过滤
if(a[i].nodeType == 3){
a[i].remove();
}
}
for(var i=0; i<a.length; i++){
document.write(a[i].innerHTML + " ");
}
各种文本
简单的说innerHTML和outerHTML、innerText的不同之处在于: innerHTML:不包含自身标签的所有内容(最常用),即自身标签里面的所有元素(里面的html标签也获取出来) innerHTML作用:拼接字符串创建HTMl元素,搭建页面 innerText:将元素的内容获取出来不包括HTML标签(纯文本) outerHTML:将自身以及子元素所有的内容都获取出来 包括HTML标签 包括自身标签
整个js阶段常用的文本只有 1.value->input type=text 2.innerHTMl-->所有元素的不包含自身标签的内容
自定义属性及getAttribute方法
写: setAttribute("属性名称","属性值") 读: getAttribute("属性名称") : 返回属性名称对应的属性值 我们可以通过setAttribute设置自定义属性eg: var d = document.getElementById("d"); d.setAttribute("heihei",123); document.write(d.getAttribute("heihei"));
属性的读写
属性 样式 offset相关属性 属性的读写: a. 对象.属性名 (.是域运算符) 写: oBox.id="hjkl"; 读:console.log(oBox.id); b. 属性名.getAttribute/.setAttribute var oBox=document.querySelector("#box"); 写: oBox.setAttribute("id","haha"); 读: console.log(oBox.getAttribute("id"));
添加自定义属性 var oBox=document.querySelector("#box"); oBox.yinghh=123; console.log(oBox.yinghh);//可以使用,方法必须统一 console.log(oBox.getAttribute("yinghh"));//(不能访问)//读写必须一致 oBox.setAttribute("a","666"); console.log(oBox.getAttribute("a")); console.log(oBox.a) 结论:添加自定义属性时,必须要用相应的方式读写
样式的读写
行内样式读: 对象名.style.属性 var oBox=document.querySelector("#box"); console.log(oBox.style.width); //100px
非行内样式读: getComputedStyle(dom对象,false)["属性名"]:返回属性值 console.log(getComputedStyle(oBox1,false)["backgroundColor"]);//rgba(0, 0, 0, 0) console.log(getComputedStyle(oBox1,false)["fontSize"]);//16px
行内样式,非行内样式的写一样: dom对象.style.属性名=属性值;
insertBefore
父节点.insertBefore(目标节点,参照节点):将目标节点添加至参照节点之前oBtn.onclick=function(){ var oLi=document.createElement("li"); oLi.innerHTML=oText.value; // value一般与input输入框联系 // oUl.insertBefore(oLi,oUl.children[2]); //把li添加到ul的第二个元素节点后面, oUl.insertBefore(oLi,null);//当ul里面有两个li时,等价于appendChild }
offset相关属性
写和读是不一样的
写:必须传入加px的字符串 oBox.style.width="500px"; oBox.style.height=500+"px"; oBox.style.left=400+"px"; oBox.style.top=400+'px'; (重点)
读:全都是纯数字 console.log(oBox.offsetWidth); console.log(oBox.offsetHeight); console.log(oBox.offsetLeft); console.log(oBox.offsetTop);
window.onscroll事件(兼容性)
滚动条:
window.onscroll=function(){
console.log("hjkl");
// 兼容性获取滚动条高度(兼容性)
var _top=document.body.scrollTop || document.documentElement.scrollTop;
console.log(_top);
}
var oBtn=document.querySelector("#btn");
oBtn.onclick=function(){
document.body.scrollTop=document.documentElement.scrollTop=0; //返回顶部
}
事件
事件:对某种元素的某种操作 事件三要素:事件元素,事件类型,[事件对象] 事件对象的作用:提供相关事件类型的属性和方法 注意事项:事件对象的产生必须要有事件 注意:要想元素动,必须要添加绝对定位, 元素动的核心问题:元素的移动实质是left和top的改变
事件对象兼容写法
事件对象的兼容写法: document.οnclick=function(evt){ var e=evt || event; }
鼠标事件对象
page:针对当前页面的左顶点 (常用) client:针对局部可视窗口的左顶点 offset:针对父元素的左顶点 用于拖拽
键盘事件对象(及兼容写法)
键盘事件对象的事件源通常都是document onkeyup:键盘弹起的时刻触发 onkeydown:键盘按下的时刻触发 onkeypress:生成一个字符时触发事件 鼠标右键事件 oncontextmenu
获取录入的Asc码值 97 a 65 A 48 '0' 32 空格 13 回车 10 Ctrl+回车
兼容性获取录入的asc码值: var key=e.keyCode || e.which || e.charCode;
ctrlKey:判断ctrl是否被按下
事件流
事件流:事件在传递的过程中,会按照由子到父元素,或者由父到子元素的方向传递(点击会随着子事件的发生父元素事件也发生)
冒泡:由子传递父
捕获:由父传递子
阻止事件流冒泡兼容写法
兼容阻止事件冒泡的写法 e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
阻止浏览器默认行为的兼容写法
兼容写法 e.preventDefault?e.preventDefault():e.returnValue=false; 或者 return false; 一般用:return false;
事件绑定的方法
-
1.通过HTML元素绑定事件
本质是将函数对象赋值给onclick属性
-
2.通过js对象绑定
var oBtn=document.querySelector("button"); oBtn.onclick=function(){ console.log("erty"); } document.onclick=function(){ alert("1"); } document.onclick=function(){ alert("2"); } //只出现弹出2
目前事件绑定的功能缺陷: 1.无法决定事件流传递是冒泡还是捕获 2.无法为相同的元素多次绑定相同的事件 为了解决这些缺陷,出现了事件监听
-
3.事件监听
好处 1.可以为相同的元素多次绑定相同的事件 2.可以决定事件流的传递是冒泡还是捕获
使用方法: DOM对象.addEventListener(去掉on的事件名,回调函数,[事件是冒泡还是捕获]);默认不写为冒泡; (true为捕获,false和默认是冒泡) eg1:可以为相同的元素多次绑定相同的事件
document.addEventListener("click",function(){ alert("1"); }); document.addEventListener("click",function(){ alert("2"); }); //1和2都弹出
当相同的元素绑定相同的事件,且捕获和冒泡同时存在时 捕获优先于冒泡
取消事件监听的绑定效果 方法1.
document.onclick=function(){ alert("1"); } document.onclick=null;
方法2.
var fun=function(){ alert(1); } document.addEventListener("click",fun); // 注意事项:两个方法的回调函数必须是同一个函数对象才可以取消事件绑定 document.removeEventListener("click",fun);
事件的委托
-
委托:让别人干你需要做的事 依赖于冒泡机制
好处1:可以通过委托机制批量为子元素添加事件,提高运行效率
注意,一般需要修改的元素,就用getElementsByTagName;
oUl.onclick=function(evt){
var e=evt||event;
//核心:获取真实的操作源
var target=e.srcElement|| e.target;
//获取真实操作源的标签名(都是大写);
//console.log(target.tagName);
if(target.tagName=="LI"){ //如果是li元素,则
target.style.backgroundColor="hotpink";
}
}
等价于:
oUl.addEventListener("click",function(evt){
var e=evt || event;
var target=e.srcElement||e.target;
if(target.tagName=="LI"){
target.style.backgroundColor="red";
}
})
事件委托的好处2 可以为未来创建的元素,提前通过父元素绑定事件
var oText=document.querySelector("input");
var oBtn=document.querySelector("button");
var oUl=document.querySelector("ul");
oUl.onmouseover=function(evt){ //鼠标放上
var e=evt||event;
var target=e.srcElement||e.target;
if(target.tagName=="LI"){
target.style.backgroundColor="pink";
}
}
oUl.onmouseout=function(evt){ //鼠标放开
var e=evt||event;
var target=e.srcElement||e.target;
if(target.tagName=="LI"){
target.style.backgroundColor="";
}
oBtn.onclick=function(){
//添加新元素
var oLi=document.createElement("li");
oLi.innerHTML=oText.value;
oUl.appendChild(oLi);
}
}
JSON对象和字符串的相互互换
json对象和字符串的相互转换 ES6提供两个函数 字符串->json对象 var str='{"name":"老王","age":18}'; var json=JSON.parse(str); console.log(json.name,json.age);
json对象 ->字符串 var json={"name":"老王","age":18}; var str=JSON.stringify(json); console.log(typeof str);
正则对象的创建
正则对象的创建
1.构造方法 var reg=new RegExp("格式控制字符串",["修饰符"]);
let reg = new RegExp(old, "g"); var reg=new RegExp("a"); //判断目标字符串是否存在一个a
2.字面量方法 var reg=/格式控制字符串/修饰符;
var reg=/a/; console.log(reg.test("abss"));
test
test 功能:判断,目标字符串是否满足正则格式,返回布尔值 参数:test(目标字符串) 返回值:布尔值 console.log(reg.test("abc"));
exec
功能:判断目标字符串是否满足正则对象的格式,将满足格式的子串返回至一个长度为1的数组 参数:exec(目标字符串) 返回值:满足条件的字串 g修饰符 golble全局 i修饰符:忽略大小写
正则格式控制字符
/格式字符串/修饰符 格式字符串:普通字符, 特殊字符: a.单个字符 b.组合字符 c.各种括号
至少包含一个a var reg=/a/; 至少包含5个a var reg=/aaaaa/; 只能包含一个a reg=/^a$/; // 注意事项: // 正则的判断只有至少或只能 // ^$同时出现同时消失 只能包含5个a reg=/^aaaaa$/; reg=/^a{5}$/; 以b开头,至少3个a 至多5个a reg=/^ba{3,5}$/; 6个5 reg=/^5{6}$/; 邮编 6位数字 reg=/\d{6}^$/; 定义一个由字母或数字或下划线组成的用户名,范围6,18之间 reg =/^\w{6,18}$/; 定义一个由字母或数字或下划线组成的用户名,范围6,18之间,首字母不能为数字 reg =/^\D\w{5,17}$/; 定义一个密码 至少6位 reg=/^.{6,}$/; //.代表任意元素 // www.baidu.com reg=/^www\.baidu\.com$/; 如何打印一个\ reg=/^\\$/; //\为转义字符 写一个3+5 reg=/^3\+5$/; 以13或15开头的手机号 a.表示或的方法|和()结合 // (5|3); reg=/^1(3|5|7)\d{9}$/; b.表示或的方法 // [157] reg=/^1[357]\d{9}$/; 范围取值:获取a-z之间的1个任意字符 reg=/^[a-zA-Z0-9]$/; 空格 reg=/^\s$/; 除了 reg=/^[^1a!]$/; //中文编码格式[\u4e00-\u9fa5] 两个中文 reg=/^[\u4e00-\u9fa5]{2}$/;
表单的验证
form action:提交的服务器地址 method:数据提交的方式,默认为get get:五菱宏光,效率高,安全性低,携带数据数据量小 post:武装押运,效率低,安全性高,携带数据量大 onblur取消焦点 onsubmit:提交事件
字符串相关方法
将正则作为参数
search
search 功能:返回匹配的字串的首位置下标 参数:search(正则对象) 返回值:找到返回字串下标,找不到返回-1 eg:var str="HelloWorld"; var reg=/wor/i; console.log(str.search(reg)); //5
match
match 功能:根据正则对象格式,返回匹配子串,存入数组 参数:match(正则对象); 返回值:数组 eg:var reg=/\d+/g; var str="123a456b789"; console.log(str.match(reg)); // ['123', '456', '789']
replace
replace方法 返回根据正则表达式进行文字替换后的字符串的复制 stringObj.replace(RegExp,replaceText) eg:var str = "gongjunjie de ge bi zhu zhe gongjunjie"; str=str.replace(/gongjunjie/g,"老王"); console.log(str); //老王 de ge bi zhu zhe 老王
正则特殊字符
单个字符: ^:正则开始 $ : 正则结束 . : 元字符, 表示任意一个字符 \. : 表示转义字符 \.表示. +: 表示其前面紧挨着的字符至少出现1次 等价{1,} * :表示其前面出现的字符至少出现过0次 等价{0,} ?: 表示其前面出现的字符至少出现过0次,至多1次 等价{0,1} | : 表示或者
组合字符: \d : 0-9之间的任意一个数字 \d只占一个位置 \D : 除了\d \w : 数字,字母 ,下划线 0-9 a-z A-Z _ \W : 除了\w \s : 空格或者空白等 \S : 除了\s
括号: {m,n}表示括号前面紧挨着的字符至少出现m个,至多出现n个 : 以b开头 至少3个a 至多5个a /^ba{3,5}&/ {m}表示括号前面紧挨着的字符只能出现m个 {m,}表示括号前面紧挨着的字符至少出现m个 [] 表示括号内的任意一个字符 [wd3h] [a-z]表示任意一个小写字母 [a-zA-Z0-9] [^ ]表示非括号内的任意一个字符 ()一般与或连用 表示优先级 [\u4e00-\u9fa5] 任意一个中文字符
let(ES6新增)
let本质和var是一样的,都是用来声明变量的
1.块级作用域:在该块的范围内,才能使用该变量,且该变量不会消失
2.暂时性死区(作用域不同的情况下,当内部变量与外部变量同名时,内部变量屏蔽外部变量) 3.变量必须先定义后使用
4.变量不能重复定义
只读变量
只读变量 const 修饰的变量为只读变量
a.变量只能读不能改
b.被const修饰的变量必须被初始化
c.必须先定义后使用
d.不能重复定义
e.块级作用域
不成文的规定,只读变量通常全部为大写
const PI=3.1415926535;
this
this:是函数的内置对象,只能在函数体内使用
a.this与事件连用:this代表触发该事件的元素
b.与普通函数连用:this代表调用该函数的对象
bind
bind 功能:修改某个函数的this指向 参数:bind(被修改的this指向) 注意事项:bind是函数对象的一个成员函数 通常用来修饰匿名函数
1.bind(修改的this指向):修改匿名函数的this指向
for...in...遍历下标 for...of...遍历元素的内容 常用于遍历set和maplet arr=[7,5,6,7]; for(let item of arr){ console.log(item); }
字符串扩展方法
includes:整串查找 console.log(str.includes("llo")); startsWith:从前往后找 console.log(str.startsWith("hella")); //字符串必须是连续的 endsWith:从后往前找 console.log(str.endsWith(".txt"));
汉字解析方式,utf-16 es6 支持utf-32 //打印该汉字对应的unicode码 console.log(str.codePointAt(0).toString(16));
箭头函数
箭头函数:匿名函数的另一种写法
注意事项: 1.如果函数的参数只有一个,则可以直接省略参数的小括号
2.如果函数体内的代码只有一行,则可以直接省略{}
let fun=a=>{
return a+10;
}
let fun=function(){
}
let fun=a=>console.log(a+10);
fun(1);
let fun1=()=>{
console.log("frfd");
}
fun1();
解构赋值
解构赋值的好处: 1.解析解构进行赋值
a.数组 // let [x,y,z]=[1,2,3]; // console.log(x,y,z); b.对象 let{name,age}={name:"老王",age:18}; // 等价于以下两行代码 let name="老王"; let age=18; console.log(name,age);
2.交换两个变量的值 方法一,中间变量交换
let [a,b] = [1,2]; let t; t = a; a = b; b = t;
方法二
let [a,b]=[1,2]; a=a+b; b=a-b; a=a-b; console.log(a,b);
方法三
let[a,b]=[1,2]; [a,b]=[b,a]; console.log(a,b);
Set集合
Set集合:没有下标,自动去重
add(参数) 向集合中添加一个元素 delete(值) 删除集合中的某个数 has(值) 判断集合中是否含有某个值 clear() 清空集合
集合的遍历需要用到for...of for(let item of set){ console.log(item); } 数组去重let arr=[36,7,8,2,22,22]; let set =new Set(arr); // Array.from将容器转换为数组 arr=Array.from(set); console.log(arr);
oUl.innerHTML="<li>1</li>"+"<li>4</li>" ES6模板字符串 oUl.innerHTML=`<li>4</li> <li>5</li> <li>4</li>` ``里面添加元素,写法和HTML里写法一样 for(let i=0;i<10;i++){ //如果模板字符串中有变量,该变量需要用${变量} oUl.innerHTML += `<li class='test'>${i}</li>`; }
map
map:映射,由键值对构成的元素集合
key唯一
set(key,value)向集合中添加一个元素:key已存在,则为修改,不存在则为添加 get(键) 根据键去取值 delete(键)删除集合的某个数 has(键)判断集合中是否含有某个值 clear 清空集合
eg: let map=new Map(); map.set("d","倪振宁"); map.set("b","方法"); map.set("c","曾经"); console.log(map.get("b")); map.clear(); console.log(map);
ES5创建类
ES5之前没有类的概念
通过函数来模拟类
构造方法模拟类
类的定义
function Student(name,id,gender){
// this在构造方法中出现时,代表new出来的对象
this.name=name;
this.gender=gender;
this.id=id;
this.eat=function(){
console.log("eat");
}
this.study=function(){
console.log("study");
}
// 如果一个成员方法使用到了其他的成员
// 必须添加前缀this
this.showValue=function(){
console.log(this.name,this.id,this.gender);
this.eat();
this.study();
}
}
// new关键字,按照类型名来创建对象 // 对象的定义 let s=new Student("乐乐",1,"F"); // 通过对象访问属性 console.log(s.name,s.id,s.gender); s.eat(); s.study(); let s1=new Student("西西",2,"F"); console.log(s1.name,s1.id,s1.gender); s1.eat(); s1.study(); s.showValue; s1.showValue;
this的三种使用场景:
a.在事件体中出现,代表触发事件的元素
b.在普通方法中出现,代表调用该方法的对象
c.在构造方法中出现,代表new出来的类对象
ES6创建类
// 语法糖衣 class Student{ // 构造方法 // 作用初始化属性 constructor(name,id,gender){ this.name=name; this.id=id; this.gender=gender; } // 其他函数构成 eat(){ console.log("eat()"); } study(){ console.log("study()"); } }
let s=new Student("西西",1,"F"); console.log(s.name,s.id,s.gender); s.eat(); s.study();
1.组合
组合:一个类的成员属性是另一个类的对象
class Birthday{
constructor(year,mouth,data){
this.year=year;
this.mouth=mouth;
this.data=data;
}
showValue(){
}
}
class Student{
constructor(name,id,gender,bir){
this.name=name;
this.id=id;
this.gender=gender;
this.bir=bir;
}
showValue(){
}
}
let bir=new Birthday(1999,4,21);
let s=new Student("纷纷",2,"M",bir);
s.bir.showValue();
s.showValue();
2.依赖
依赖:一个类的成员方法的参数,是另一个类的对象
eg: 有一辆小汽车行驶在一条公路上,计算这辆小汽车以60km/小时的速度,行驶1000km需要多久 // 面向对象分析问题的方法 // 1.分析问题找出所有对象:---设计类时,先有对象后有类 // 2.根据对象抽象出其属性和行为创建类时 -----创建对象时,先有类后有对象 // 3.各个对象各司其职
class Car{
constructor(speed){
this.speed=speed;
}
//依赖
time(r){
return r.length/this.speed;
}
}
class Road{
constructor(length){
this.length=length;
}
}
let c=new Car(60);
let r=new Road(1000);
console.log(c.time(r));
PHP
1.服务器:
-
C/S架构:client/Server
(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销, 可以充分利用两端硬件环境的优势。 开发C/S架构可以采用多种语言,包括Java,C++,C#,以及Dephi等
-
B/S架构: Browser/Server
即Browser/Server(浏览器/服务器)结构,是随着技术Internet的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下, 用户界面完全通过WWW浏览器实现。前端在大部分企业就是做浏览器端展现相关的工作,会用到html,css,js,ps,ai等等,而“后端”的主要工作室程序开发、数据处理了,比如:php,asp,mysql,mssql。
浏览器----发送请求--->服务器
服务器----发出相应----->浏览器
php的优缺点
PHP是服务器端语言 PHP优点: 跨平台 ,同时支持多种数据库 安全性和效率好 使用成本低 ( linux apache mysql PHP内核) 相对jsp ,和 asp.net 简单 开发源码(可以做二次开发) / 开源软件 在PHP4 PHP5 以及即将发布PHP6 中更好的支持 面向对象
缺点: 安装比较复杂,配置比较多 太灵活,解释执行(编译执行),所以有些错误,到真的运行的时候才会暴露 服务器端除了PHP还有,JSP(java),ASP,python,nodeJS,go等等。 PHP:personal home page;
环境搭建
phpStudy是搭建服务器的工具,我们需要把php的代码放在phpStudy工具里的“www”目录下,“www”目录就是服务器的目录,即放置项目代码的目录。 如:把index.html文件拷贝至www下,则用服务器的方式打开index.html的做法是:在浏览器中输入http://ip地址/index.html 假如: www的全路径是:D:\phpStudy\WWW, ip地址是:10.35.165.10/文件名
PHP语句
文件扩展名 php 代码写在<?php 与 ?>之间 PHP代码每句话以分号结束
PHP的注释: 多行: /*内容*/ 单行用:// 或 #<?php echo "hello,world"; ?>
环形地址:可以代表本机IP地址,localhost 或 127.0.0.1 http://localhost/testPhp/HelloWorld.php http://127.0.0.1/testPhp/HelloWorld.php
中文编码格式 header("Content-type:text/html;charset=utf-8");
PHP语法
php中,定义一个变量要以$符号打头,变量名区分大小写 php 的变量的数据类型,是变化的,php变量的数据类型是由运行时的上下文决定。
字符串的连接用.
count 用来统计数组的长度
如:$age = 250; 如: $a=90; //相当于我们定义了一个变量 $a,并赋值90 $a=”hello”; //表示$a 的类型变化.
字符串的连接用. echo "Hello World" ."</br>". "大黄";
if(条件表达式){ //n多语句; }else{ //n多语句; } switch分支语句 switch(表达式){ case 常量1://n多语句;break; case 常量2://n多语句break; default: //n多语句;break; } eg:$a = 123; $b = 456; $c = 0; if($a>$b){ $c = $a; }else{ $c = $a; } echo $c
PHP的流程控制 循环:(break,continue) for(循环初值; 循环的条件; 步长){ } for($i=0; $i<10; $i++){ echo "我今年".$i."岁了"."</br>"; }
PHP的函数 <?php function add($a,$b){ return $a+$b; } echo add(1,2); ?>
PHP的数组 $arr = Array(11,22,33,44,55); //count 用来统计数组的长度 for($i=0; $i<count($arr); $i++){ echo $arr[$i]."</br>"; }
PHP生成动态页面 .php文件中 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <ul> <?php for($i=0; $i<10; $i++){ ?> <li><?php echo $i ?></li> <?php } ?> </ul> </body> </html>
PHP接收前端的数据
$_POST['参数名‘] $_GET["参数名"] $_REQUEST["参数名"]; 前后端一般一致,如前端用get,后端也用get,后端用request可以接收前端的get和post的数据
数据库
数据库概念:
* 库:仓库
* 表:一个仓库被分为了许多部分,很像类
* 字段:很像类的每个属性。
* 每个字段的数据类型:
int ----> 整数 blob -----> 二进制数据 varchar/char ----->字符串 date -----> 日期 varchar(可变的)
常见的数据库
关系型数据库:Oracle、MySQL、SQLServer、DB2、sybase
(关系型数据库:之间有联系)
非关系型的数据库:Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite, HBase,CouchDB,Hypertable, Riak,Ti,
数据库的编辑
-
1.创建数据库:
可视化:点击鼠标右键 代码: create database 数据库名 如: create database db20170203
-
2.创建表:
create table 表名(字段1,字段2...字段N) eg: create table Student ( stuId int, stuName varchar(20), stuGender char(4), stuAge int )
序言
JavaScript发展历史(JS)
1. 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版,这是世界上第一款比较成熟的网络浏览器,轰动一时。但是这是一款名副其实的浏览器--只能浏览页面,浏览器无法与用户互动,当时解决这个问题有两个办法,一个是采用现有的语言,许它们直接嵌入网页。另一个是发明一种全新的语言。 liveScript ==> javaScript ==> ECMAscript 2. 1995年Sun公司将Oak语言改名为Java,正式向市场推出。Sun公司大肆宣传,许诺这种语言可以"一次编写,到处运 行"(Write Once, Run Anywhere),它看上去很可能成为未来的主宰。 3. 网景公司动了心,决定与Sun公司结成联盟 4. 34岁的系统程序员Brendan Eich登场了。1995年4月,网景公司录用了他,他只用10天时间就把Javascript设计出来了。(多肽语言) 5. (1)借鉴C语言的基本语法; (2)借鉴Java语言的数据类型和内存管理; (3)借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位; (4)借鉴Self语言,使用基于原型(prototype)的继承机制。
JavaScript能干什么
1. 常见的网页效果【表单验证,轮播图。。。】 2. 与H5配合实现游戏【水果忍者: http://www.jq22.com/demo/html5-fruit-ninja/】 3. 实现应用级别的程序【http://naotu.baidu.com】 4. 实现统计效果【http://echarts.baidu.com/examples/】 5. 地理定位等功能【http://lbsyun.baidu.com/jsdemo.htm#i4_5】 6. 在线学编程【https://codecombat.163.com/play/】 7. js可以实现人工智能【面部识别】 8. js可以操作页面的元素 1. 先获取两个输入框的值(盲点) // a). 获取元素 输入框 document.getElementById(): 通过id获取元素 // b). 获取元素 输入框的值 document.getElementById().value 9. 。。。
JavaScript的组成
1. ECMASCRIPT: 定义了javascript的语法规范,描述了语言的基本语法和数据类型 2. BOM (Browser Object Model): 浏览器对象模型 3. DOM (Document Object Model): 文档对象模型,通过 DOM 可以操作页面中的元素。比如: 增加个 div,减少个 div,给div 换个位置等
总结: JS 就是通过固定的语法去操作 浏览器 和 标签结构 来实现网页上的各种效果
JavaScript代码的书写位置
行内式 JS 代码(不推荐)
<!-- 写在 a 标签的 href 属性上 --> <a href="javascript:alert('我是一个弹出层');">点击一下试试</a> <!-- 写在其他元素上 --> <div οnclick="alert('我是一个弹出层')">点一下试试看</div> <!-- 注:onclick 是一个事件(点击事件),当点击元素的时候执行后面的 js 代码 -->
内嵌式 JS 代码
<!-- 在 html 页面书写一个 script 标签,标签内部书写 js 代码 --> <script type="text/javascript"> alert('我是一个弹出层') </script> <!-- 注:script 标签可以放在 head 里面也可以放在 body 里面 -->
外链式 JS 代码(推荐)
// 我是 index.js 文件 alert('我是一个弹出层')
<!-- 我是一个 html 文件 --> <!-- 通过 script 标签的 src 属性,把写好的 js 文件引入页面 --> <script src="index.js"></script> <!-- 一个页面可以引入多个 js 文件 --> <script src="index1.js"></script> <script src="index2.js"></script> <script src="index3.js"></script>
JS 中的注释
单行注释
// 我是一个单行注释 // 下面代码表示在浏览器里面出现一个弹出层 alert('我是一个弹出层')
多行注释
/* 注释的代码不会执行 alert('我是一个弹出层') alert('我是一个弹出层') */ alert('我是一个弹出层')
变量(重点)
定义变量及赋值
// 定义一个变量 var num; // 给一个变量赋值 num = 100; // 定义一个变量的同时给其赋值 var num2 = 200;
变量的命名规则和命名规范
数据类型(重点)
基本数据类型
复杂数据类型(暂时先不讲)
判断数据类型
// 第一种使用方式 var n1 = 100; console.log(typeof n1); // number // 第二种使用方式 var s1 = 'abcdefg'; console.log(typeof(s1));//string
判断数据类型的注意点
控制台:检测手段(数字类型和字符串类型):看颜色,黑色字符串,蓝色是数字类型 typeof x typeof(x) typeof的返回值是什么(类型的返回值)? 'number' typeof 10 'string' 'x' 'boolean' true 'undefined' 'object'---> null typeof的返回值的类型是什么? 字符串 typeof typeof 'hhah'; 'string'
判断一个变量是不是数字
isNaN()检测是否为非数字,如果不是数字,返回true,如果是数字,返回false 底层会调用Number() isNaN()等价于isNaN(Number(x)) isNaN('100px')---》true isNaN('100')---》false // 如果变量是一个数字 var n1 = 100; console.log(isNaN(n1)); //=> false // 如果变量不是一个数字 var s1 = 'Jack' console.log(isNaN(s1)); //=> true
数据类型转换
其他数据类型转成数值
其他数据类型转成字符串
其他数据类型转成布尔
运算符
数学运算符
赋值运算符
比较运算符
逻辑运算符
自增自减运算符(一元运算符)
流程控制
流程控制
流程控制概念
顺序:根据代码的书写顺序,从上向下一行一行执行
选择:根据条件的真假,选择执行某种响应的结果
表达式:是由数字、运算符、变量等组成的式子
表达式最终都会有一个结果,返回给开发者,称为返回值
简单理解:流程控制就是来控制代码按照一定结构顺序来执行
流程控制主要有三种结构,分别是顺序结构、分支结构和循环结构,代表三种代码执行的顺序。
顺序流程控制
顺序结构是程序中最简单、最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
分支流程控制
分支结构
if条件分支结构
if 语句
if else 语句
if else if ... 语句
if else if … else 语句
SWITCH 条件分支结构
三元运算(扩展)
打断点
f12-- > sources --> 点到你的页面 --> 打断点 --> 刷新页面 --> step over-->让代码执行下去 // -->离开时关断点 一般循环语句里面,打断点可以监控for循环里重新赋值的变量,在step into next里面检查,循环值的变化
循环结构
WHILE 循环
DO WHILE 循环
FOR 循环
# 循环嵌套
对于循环嵌套:外层循环控制行数,内层循环控制每行的个数
BREAK 终止循环
CONTINUE 结束本次循环
json对象
json数据格式:可用来描述复杂的对象,将多个繁琐的属性或方法封装成一个整体 a.定义:json是由若干个键值对构成的,若干个键值对用逗号分开 且键值对可以包含属性或者方法 var stu={ key1:value1, key2:value2, ... keyN:valueN, } 注意事项:key全部用双引号引起来(不引也不报错); var stu={ "name":"信息工程", "age":200, "id":123 }
json对象属性的使用
json对象属性的使用 方法1:对象名.属性名 console.log(stu.name,stu.age,stu.gender); 1.打点 console.log(stu.age); console.log(stu.id); console.log(stu.name); 方法2:下标法 对象名["索引"],索引相当于下标 var str="id"; console.log(stu["name"],stu["age"],stu[str]); console.log(stu["name"]); console.log(stu["age"]); console.log(stu["id"]); 注意:下标不是变量则写""; 3.json的遍历; for(var 索引变量名 in 容器){ 循环体 } for(var index in stu){ // for...in不支持打点的方式访问value console.log(stu[index]); console.log(stu.index); } var arr=[7,8,6,3,2,1,23]; for (var index in arr){ console.log(index); } 索引下标 4.添加对象自定义属性 对象名.新的属性=数值; var stu={ "name":"信息工程", "age":200, "id":123 } stu.name='写写画画';//key值存在则被修改 console.log(stu.name); stu.gender='M'; console.log(stu.gender);//key值不存在则为添加 5.添加方法的json对象 var stu={ "name":"乐乐", "age":6, "eat":function(){ console.log("eat"); }, "showValue":function(){ // 如果某个成员方法要使用其成员属性或方法 // 必须加this前缀(this目前代表调用该函数的对象本身) console.log(this.name,this.age); this.eat(); } } console.log(stu.name,stu.age); stu.eat(); stu.showValue(); var stu={ "name":"高明",//var name="高明"; "age":18, "eat":function(){ //如果json对象的函数中需要使用其他属性或者函数 // 需要加前缀this // this代表调用该函数的对象本身 console.log(this.name,this.age,this.id); this.eat(); } }
严格模式
严格模式:无法使用未被声明(定义)的变量,但是不限制声明顺序 eg: "use strict"; a=1233; console.log(a); 这样使用会报错 "use strict"; a=1233; console.log(a); var a; 这样使用正确
数组ES5新增方法
节点的遍历
节点的遍历 document.body var str=document.body.firstElementChild.nextElementSibling.firstElementChild.nextElementSibling.innerHTML; console.log(str); // 2 node Type返回当前节点的类型,返回值判断 元素节点:1(返回值) 文本节点:3
document文档对象
每个载入浏览器的 HTML 文档都会成为 Document 对象。 document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问 document 对象是 window 对象的一部分,可通过 window.document 属性对其进行访问 1.document.write():特点,拥有字符串解析 2.特点:当参与事件时,会覆盖原网页 -------- 作用: 找对象 1.document.getElementById("id名");返回对拥有指定 id 的第一个对象的引用。 2.document.getElementsByTagName("标签名");返回带有指定标签名的对象集合,数组。 3.document.getElementsByName("name名");返回带有指定名称的对象集合。 4.document.getElementsByClassName("类名"); 通过类名返回,返回数组; 5.document.querySelector("选择器");通过选择器返回,获取单个ID,类,标签 6.document.querySelectorAll("选择器");获取类,标签批量元素,返回数组
DOM
DOM(Document Object Model),文档对象模型。
节点和节点的关系
根据层次关系访问节点: (包括文本和元素) parentNode 返回节点的父节点 childNodes 返回子节点集合,数组名[i]访问子节点 nextSibling 下一个节点 previousSibling 上一个节点
通过层级关系访问元素节点
firstElementChild 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 lastElementChild 返回节点的最后一个子节点 nextElementSibling 下一个节点 previousElementSibling 上一个节点 parentNode 返回节点的父节点 childNodes 返回子节点集合,数组名[i]访问子节点 eg: var str = a.firstElementChild.innerHTML;
节点类型
节点类型: 通过nodeType属性来判断节点类型 1代表元素节点 3代表文本节点 <p id = "_p">123</p> var p = document.getElementById("_p"); //元素类型 1 document.write(p.nodeType); //文本类型 document.write(p.firstChild.nodeType);//3 //属性节点 document.write(p.getAttributeNode("id").nodeType);//2
节点操作
(DOM是树形结构,增加需要生成元素,然后连接元素建立关系) 增加节点:需要两个步骤 a.创建元素 b.追加元素 document.createElement(HTML标签名) //创建一个元素节点 node.appendChild(newChild) //newChild 被添加到孩子列表中的末端。 node.insertBefore(newChild, referenceNode) // 将 newChild 节点插入到 referenceNode 之前。 node.removeChild(oldChild) //删除 oldChild子节点。 var oH1=document.createElement("h1");//创建h1元素 oH1.innerHTML="爱高";//给创建的元素赋值 //追加 document.body.appendChild(oH1);
针对这种情况,我们需要过滤空白节点:
childNodes:批量获取父元素的子元素,存储在至数组中(返回元素和文本节点) children:批量获取父元素的子元素,存储在数组中(只返回元素节点) 过滤文本节点: for(var i=0; i<a.length; i++){ //删除空白节点 //如果节点为空白节点,则根据nodeType过滤 if(a[i].nodeType == 3){ a[i].remove(); } } for(var i=0; i<a.length; i++){ document.write(a[i].innerHTML + " "); }
各种文本
简单的说innerHTML和outerHTML、innerText的不同之处在于: innerHTML:不包含自身标签的所有内容(最常用),即自身标签里面的所有元素(里面的html标签也获取出来) innerHTML作用:拼接字符串创建HTMl元素,搭建页面 innerText:将元素的内容获取出来不包括HTML标签(纯文本) outerHTML:将自身以及子元素所有的内容都获取出来 包括HTML标签 包括自身标签 整个js阶段常用的文本只有 1.value->input type=text 2.innerHTMl-->所有元素的不包含自身标签的内容
自定义属性及getAttribute方法
写: setAttribute("属性名称","属性值") 读: getAttribute("属性名称") : 返回属性名称对应的属性值 我们可以通过setAttribute设置自定义属性 eg: var d = document.getElementById("d"); d.setAttribute("heihei",123); document.write(d.getAttribute("heihei"));
属性的读写
属性 样式 offset相关属性 属性的读写: a. 对象.属性名 (.是域运算符) 写: oBox.id="hjkl"; 读:console.log(oBox.id); b. 属性名.getAttribute/.setAttribute var oBox=document.querySelector("#box"); 写: oBox.setAttribute("id","haha"); 读: console.log(oBox.getAttribute("id")); 添加自定义属性 var oBox=document.querySelector("#box"); oBox.yinghh=123; console.log(oBox.yinghh);//可以使用,方法必须统一 console.log(oBox.getAttribute("yinghh"));//(不能访问)//读写必须一致 oBox.setAttribute("a","666"); console.log(oBox.getAttribute("a")); console.log(oBox.a); // 结论:添加自定义属性时,必须要用相应的方式读写
样式的读写
行内样式读: 对象名.style.属性 var oBox=document.querySelector("#box"); console.log(oBox.style.width); //100px 非行内样式读: getComputedStyle(dom对象,false)["属性名"]:返回属性值 console.log(getComputedStyle(oBox1,false)["backgroundColor"]);//rgba(0, 0, 0, 0) console.log(getComputedStyle(oBox1,false)["fontSize"]);//16px 行内样式,非行内样式的写一样: dom对象.style.属性名=属性值;
insertBefore
父节点.insertBefore(目标节点,参照节点):将目标节点添加至参照节点之前 oBtn.οnclick=function(){ var oLi=document.createElement("li"); oLi.innerHTML=oText.value; // value一般与input输入框联系 // oUl.insertBefore(oLi,oUl.children[2]); //把li添加到ul的第二个元素节点后面, oUl.insertBefore(oLi,null);//当ul里面有两个li时,等价于appendChild }
offset相关属性
写和读是不一样的
写:必须传入加px的字符串 oBox.style.width="500px"; oBox.style.height=500+"px"; oBox.style.left=400+"px"; oBox.style.top=400+'px'; (重点) 读:全都是纯数字 console.log(oBox.offsetWidth); console.log(oBox.offsetHeight); console.log(oBox.offsetLeft); console.log(oBox.offsetTop);
window.onscroll事件(兼容性)
滚动条: window.οnscrοll=function(){ console.log("hjkl"); // 兼容性获取滚动条高度(兼容性) var _top=document.body.scrollTop || document.documentElement.scrollTop; console.log(_top); } var oBtn=document.querySelector("#btn"); oBtn.οnclick=function(){ document.body.scrollTop=document.documentElement.scrollTop=0; //返回顶部 }
事件
事件:对某种元素的某种操作 事件三要素:事件元素,事件类型,[事件对象] 事件对象的作用:提供相关事件类型的属性和方法 注意事项:事件对象的产生必须要有事件 注意:要想元素动,必须要添加绝对定位, 元素动的核心问题:元素的移动实质是left和top的改变
事件对象兼容写法
事件对象的兼容写法: document.οnclick=function(evt){ var e=evt || event; }
鼠标事件对象
page:针对当前页面的左顶点 (常用) client:针对局部可视窗口的左顶点 offset:针对父元素的左顶点 用于拖拽
键盘事件对象(及兼容写法)
键盘事件对象的事件源通常都是document onkeyup:键盘弹起的时刻触发 onkeydown:键盘按下的时刻触发 onkeypress:生成一个字符时触发事件 鼠标右键事件 oncontextmenu 获取录入的Asc码值 97 a 65 A 48 '0' 32 空格 13 回车 10 Ctrl+回车 兼容性获取录入的asc码值: var key=e.keyCode || e.which || e.charCode; ctrlKey:判断ctrl是否被按下
事件流
事件流:事件在传递的过程中,会按照由子到父元素,或者由父到子元素的方向传递(点击会随着子事件的发生父元素事件也发生)
阻止事件流冒泡兼容写法
兼容阻止事件冒泡的写法 e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
阻止浏览器默认行为的兼容写法
兼容写法 e.preventDefault?e.preventDefault():e.returnValue=false; 相当于 return false; 所以用:return false;
事件绑定的方法
a.数组 // let [x,y,z]=[1,2,3]; // console.log(x,y,z); b.对象 let{name,age}={name:"老王",age:18}; // 等价于以下两行代码 let name="老王"; let age=18; console.log(name,age);
交换两个变量的值
2.交换两个变量的值 方法一,中间变量交换
let [a,b] = [1,2]; let t; t = a; a = b; b = t;
方法二
let [a,b]=[1,2]; a=a+b; b=a-b; a=a-b; console.log(a,b);
方法三
let[a,b]=[1,2]; [a,b]=[b,a]; console.log(a,b);
Set集合
Set集合:没有下标,自动去重
add(参数) 向集合中添加一个元素 delete(值) 删除集合中的某个数 has(值) 判断集合中是否含有某个值 clear() 清空集合 集合的遍历需要用到for...of for(let item of set){ console.log(item); } 数组去重 let arr=[36,7,8,2,22,22]; let set =new Set(arr); // Array.from将容器转换为数组 arr=Array.from(set); console.log(arr); oUl.innerHTML="<li>1</li>"+"<li>4</li>" ================================== ES6模板字符串 oUl.innerHTML=`<li>4</li> <li>5</li> <li>4</li>` ``里面添加元素,写法和HTML里写法一样 for(let i=0;i<10;i++){ //如果模板字符串中有变量,该变量需要用${变量} oUl.innerHTML += `<li class='test'>${i}</li>`; }
map
map:映射,由键值对构成的元素集合
key唯一
set(key,value)向集合中添加一个元素:key已存在,则为修改,不存在则为添加 get(键) 根据键去取值 delete(键)删除集合的某个数 has(键)判断集合中是否含有某个值 clear 清空集合 eg: let map=new Map(); map.set("d","倪振宁"); map.set("b","方法"); map.set("c","曾经"); console.log(map.get("b")); map.clear(); console.log(map);
ES5创建类
ES5之前没有类的概念
通过函数来模拟类
构造方法模拟类
类的定义
function Student(name,id,gender){ // this在构造方法中出现时,代表new出来的对象 this.name=name; this.gender=gender; this.id=id; this.eat=function(){ console.log("eat"); } this.study=function(){ console.log("study"); } // 如果一个成员方法使用到了其他的成员 // 必须添加前缀this this.showValue=function(){ console.log(this.name,this.id,this.gender); this.eat(); this.study(); } } // new关键字,按照类型名来创建对象 // 对象的定义 let s=new Student("乐乐",1,"F"); // 通过对象访问属性 console.log(s.name,s.id,s.gender); s.eat(); s.study(); let s1=new Student("西西",2,"F"); console.log(s1.name,s1.id,s1.gender); s1.eat(); s1.study(); s.showValue; s1.showValue;
this的三种使用场景:
a.在事件体中出现,代表触发事件的元素
b.在普通方法中出现,代表调用该方法的对象
c.在构造方法中出现,代表new出来的类对象
ES6创建类
// 语法糖衣 class Student{ // 构造方法 // 作用初始化属性 constructor(name,id,gender){ this.name=name; this.id=id; this.gender=gender; } // 其他函数构成 eat(){ console.log("eat()"); } study(){ console.log("study()"); } } let s=new Student("西西",1,"F"); console.log(s.name,s.id,s.gender); s.eat(); s.study();
1.组合
组合:一个类的成员属性是另一个类的对象
class Birthday{ constructor(year,mouth,data){ this.year=year; this.mouth=mouth; this.data=data; } showValue(){ } } class Student{ constructor(name,id,gender,bir){ this.name=name; this.id=id; this.gender=gender; this.bir=bir; } showValue(){ } } let bir=new Birthday(1999,4,21); let s=new Student("纷纷",2,"M",bir); s.bir.showValue(); s.showValue();
2.依赖
依赖:一个类的成员方法的参数,是另一个类的对象
eg: 有一辆小汽车行驶在一条公路上,计算这辆小汽车以60km/小时的速度,行驶1000km需要多久 // 面向对象分析问题的方法 // 1.分析问题找出所有对象:---设计类时,先有对象后有类 // 2.根据对象抽象出其属性和行为创建类时 -----创建对象时,先有类后有对象 // 3.各个对象各司其职 class Car{ constructor(speed){ this.speed=speed; } //依赖 time(r){ return r.length/this.speed; } } class Road{ constructor(length){ this.length=length; } } let c=new Car(60); let r=new Road(1000); console.log(c.time(r));
###
PHP
1.服务器:
浏览器----发送请求--->服务器
服务器----发出相应----->浏览器
php的优缺点
PHP是服务器端语言 PHP优点: 跨平台 ,同时支持多种数据库 安全性和效率好 使用成本低 ( linux apache mysql PHP内核) 相对jsp ,和 asp.net 简单 开发源码(可以做二次开发) / 开源软件 在PHP4 PHP5 以及即将发布PHP6 中更好的支持 面向对象 缺点: 安装比较复杂,配置比较多 太灵活,解释执行(编译执行),所以有些错误,到真的运行的时候才会暴露 服务器端除了PHP还有,JSP(java),ASP,python,nodeJS,go等等。 PHP:personal home page;
环境搭建
phpStudy是搭建服务器的工具,我们需要把php的代码放在phpStudy工具里的“www”目录下,“www”目录就是服务器的目录,即放置项目代码的目录。 如:把index.html文件拷贝至www下,则用服务器的方式打开index.html的做法是:在浏览器中输入http://ip地址/index.html 假如: www的全路径是:D:\phpStudy\WWW, ip地址是:10.35.165.10/文件名
PHP语句
* 文件扩展名 php * 代码写在<?php 与 ?>之间 * PHP代码每句话以分号结束 * PHP的注释: 多行: /*内容*/ 单行用:// 或 # eg: <?php echo "hello,world"; ?> 环形地址:可以代表本机IP地址,localhost 或 127.0.0.1 http://localhost/testPhp/HelloWorld.php http://127.0.0.1/testPhp/HelloWorld.php ===================== 中文编码格式 header("Content-type:text/html;charset=utf-8");
PHP语法
php中,定义一个变量要以$符号打头,变量名区分大小写 php 的变量的数据类型,是变化的,php变量的数据类型是由运行时的上下文决定。
字符串的连接用.
count 用来统计数组的长度
如:$age = 250; 如: $a=90; //相当于我们定义了一个变量 $a,并赋值90 $a=”hello”; //表示$a 的类型变化. --------------------- 字符串的连接用. echo "Hello World" ."</br>". "大黄"; ---------------------- if(条件表达式){ //n多语句; }else{ //n多语句; } switch分支语句 switch(表达式){ case 常量1://n多语句;break; case 常量2://n多语句break; default: //n多语句;break; } eg: $a = 123; $b = 456; $c = 0; if($a>$b){ $c = $a; }else{ $c = $a; } echo $c ------------------------ * PHP的流程控制 * 循环:(break,continue) for(循环初值; 循环的条件; 步长){ } for($i=0; $i<10; $i++){ echo "我今年".$i."岁了"."</br>"; } ------------------------------- * PHP的函数 <?php function add($a,$b){ return $a+$b; } echo add(1,2); ?> -------------------- * PHP的数组 $arr = Array(11,22,33,44,55); //count 用来统计数组的长度 for($i=0; $i<count($arr); $i++){ echo $arr[$i]."</br>"; } ------------------------------ PHP生成动态页面 .php文件中 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <ul> <?php for($i=0; $i<10; $i++){ ?> <li><?php echo $i ?></li> <?php } ?> </ul> </body> </html>
PHP接收前端的数据
$_POST['参数名‘] $_GET["参数名"] $_REQUEST["参数名"]; 前后端一般一致,如前端用get,后端也用get,后端用request可以接收前端的get和post的数据
数据库
数据库概念:
* 库:仓库
* 表:一个仓库被分为了许多部分,很像类
* 字段:很像类的每个属性。
* 每个字段的数据类型:
int ----> 整数 blob -----> 二进制数据 varchar/char ----->字符串 date -----> 日期 varchar(可变的)
常见的数据库
数据库的编辑
create table 表名(字段1,字段2...字段N) eg: create table Student ( stuId int, stuName varchar(20), stuGender char(4), stuAge int )
this
this:是函数的内置对象,只能在函数体内使用
a.this与事件连用:this代表触发该事件的元素
b.与普通函数连用:this代表调用该函数的对象
bind
bind 功能:修改某个函数的this指向 参数:bind(被修改的this指向) 注意事项:bind是函数对象的一个成员函数 通常用来修饰匿名函数
1.bind(修改的this指向):修改匿名函数的this指向
for...in...遍历下标 for...of...遍历元素的内容 常用于遍历set和map let arr=[7,5,6,7]; for(let item of arr){ console.log(item); }
字符串扩展方法
includes:整串查找 console.log(str.includes("llo")); startsWith:从前往后找 console.log(str.startsWith("hella")); //字符串必须是连续的 endsWith:从后往前找 console.log(str.endsWith(".txt")); 汉字解析方式,utf-16 es6 支持utf-32 //打印该汉字对应的unicode码 console.log(str.codePointAt(0).toString(16));
箭头函数
箭头函数:匿名函数的另一种写法
注意事项: 1.如果函数的参数只有一个,则可以直接省略参数的小括号
2.如果函数体内的代码只有一行,则可以直接省略{}
let fun=a=>{ return a+10; } let fun=function(){ } let fun=a=>console.log(a+10); fun(1); let fun1=()=>{ console.log("frfd"); } fun1();
解构赋值
解构赋值的好处: 1.解析解构进行赋值
-
3.sql语句:增,删,查,改
--增--------------------------------------- insert into 表名[字段1,字段2...字段N] values(值1,值2,值N); eg: insert into student(name, sex, age) values("孙丽华", "女", 21); insert into Student values(1,"大黄",666,18); insert into Student values(3,"小明",666,18); insert into Student(stuId,stuName) values(2,"laowang"); --删 直接删除整个表的内容,但是表还在---------------- delete from 表名 where 条件; eg: * delete from students; 删除表中的所有数据, * delete from students where id=2; //删除表中,id是2的数据。 * delete from students where age<20;
delete from Student; --整个表都删掉 drop table Student; --where 条件 类似于if delete from Student where stuName = "大黄"
--OR类似于 || delete from Student where stuId = 1 OR stuName = "小明";
--AND类似于&& delete from Student Where stuName = "大黄" AND stuid = 1;
--改 update 表明 set 字段1=值1,字段2=值2... WHERE 更新条件; update student set stuName = "啦啦啦",stuId = 12323 where stuname = "嘿嘿";
--查 select 列名称 from 表名称 [查询条件]; * select name, age from students; * select * from students; * select * from students where age > 21 ; * select * from students where name like "%王%"; --模糊查询 * select * from students where id<5 and age>20; 如: select stuAge,stuId,stuAge from Student; select*from Student;
PHP连接MySql
mysql_connect(servername,username,password);
参数描述
servername可选。规定要连接的服务器。默认是 "localhost:3306"。
username可选。规定登录所使用的用户名。默认值是拥有服务器进程的用户的名称。
password可选。规定登录所用的密码。默认是 ""。
-
1.创建数据库连接对象
$conn = mysql_connect("localhost","root","root");
-
2.选择数据库
mysql_select_db("xa1901");
-
3.数据库操作
数据库查询 mysql_query(sql语句,连接对象); ----------------------------- 增: mysql_query("insert into student values(999,'大王','M','23')",$conn); 删: mysql_query("delete from student where stuName = '小明'",$conn); 改: mysql_query("update student set stuname='蝙蝠侠' where stuid = 999",$conn); ============ 查 返回结果集,类似于一张表 mysql_num_rows(结果集):返回当前结果集对应的记录数 $result=mysql_query("select * from student",$conn); $row=mysql_num_rows($result); 一般我们需要的是表格的东西,而不是表格记录的个数,所以一般用作判断 登录注册的条件,返回1,则说明数据存在,只需要登录 通常作为登录注册的判断条件 $result=mysql_query("select * from student where stuName='哈哈'",$conn); if(mysql_num_rows($result)==1){ echo "登录成功"; }else{ echo "登录失败"; } // 获取数据库中的某条记录 // mysql_fetch_assoc("结果集"):返回当前游标所指向的记录,以对象的方式存储 // 注意事项:mysql_fetch_assoc方法每执行完一次,游标会自动下移 $result=mysql_query("select * from student",$conn); while($obj=mysql_fetch_assoc($result)){ echo $obj["stuId"]."". $obj["stuName"]."".$obj["stuGender"]."". $obj["stuAge"].""."<br>"; }
-
4.关闭数据库
mysql_close($conn);
eg:
<?php header("Content-type:text/html;charset=utf-8"); //$conn = mysql_connect("localhost","root","root"); //创建数据库连接对象 $conn = mysql_connect("localhost","root","root"); if($conn){ echo "连接成功"."</br>"; //选择数据库 mysql_select_db("xa1901"); }else{ die("Could not connect:" . mysql_error()); } //数据库查询 //mysql_query(sql语句,连接对象); //增 // mysql_query("insert into student values(999,'大王','M','23')",$conn); //删 //mysql_query("delete from student where stuName = '小明'",$conn); //改 //mysql_query("update student set stuname='蝙蝠侠' where stuid = 999",$conn); //返回的是一个表格 $result = mysql_query("select * from student where stuid = 2",$conn); //返回结果集中的字段数,也就是列数 $result_col = mysql_num_fields($result); //返回行数 $result_row = mysql_num_rows($result); echo $result_row; if($result_row == 1){ echo "存在"; }else{ echo "不存在"; //判断结果集的行数 if(mysql_num_rows($result)>0){ //将结果集放到数组$rows while($rows = mysql_fetch_assoc($result)){ echo $rows["stuName"]." ".$rows["stuAge"]; } } } mysql_close($conn); ?>
*注意事项:
1.php的变量名在字符串中,依然代表变量的内容
2.字符串嵌套字符串必须转义
cookie
cookie的存
存: document.cookie="key=value"; eg: document.cookie="name=laowang";
多个cookie都要分开定义 document.cookie="age=18"; 没有key的时候为增,有key的时候为改 document.cookie="name=huanghh";
取:每两组键值对之间用户分号和空格隔开 // age=18; name=huanghh console.log(document.cookie);
cookie的生命周期 会话级别: document.cookie="key=value"; eg: document.cookie="name=caoboyong";
长生命周期: document.cookie="key=value;expires="+标准日期对象; eg: let date=new Date(); date.setDate(date.getDate()+10); document.cookie="name=laowang;expires="+date;
cookie没有直接删除 // cookie只能侧面删除 // a.将key对应的value设置成字符串 // b.将expires设置为-1 document.cookie="key='';expires=-1";
同步与异步
同步:代码按照顺序一步一步执行,遇到需要消耗等待时间的代码块,会阻塞代码执行
异步:遇到需要消耗时间的代码块,非阻塞程序执行,先去执行后续代码
异步代码:和消耗等待时间有关
a.定时器
b.事件体
document.οnclick=function(){ console.log("gghhh"); //异步代码 }
c.发送请求和接收响应
同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的, 只有接收到返回的值或消息后才往下执行其他的命令。 异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程, 那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。
注意:当同步代码和异步代码同时存在时,同步代码优先执行,与书写顺序无关
eg:
<?php header("Content-type:text/html;charset=utf-8"); //$conn = mysql_connect("localhost","root","root"); //创建数据库连接对象 $conn = mysql_connect("localhost","root","root"); if($conn){ echo "连接成功"."</br>"; //选择数据库 mysql_select_db("xa1901"); }else{ die("Could not connect:" . mysql_error()); } //数据库查询 //mysql_query(sql语句,连接对象); //增 // mysql_query("insert into student values(999,'大王','M','23')",$conn); //删 //mysql_query("delete from student where stuName = '小明'",$conn); //改 //mysql_query("update student set stuname='蝙蝠侠' where stuid = 999",$conn); //返回的是一个表格 $result = mysql_query("select * from student where stuid = 2",$conn); //返回结果集中的字段数,也就是列数 $result_col = mysql_num_fields($result); //返回行数 $result_row = mysql_num_rows($result); echo $result_row; if($result_row == 1){ echo "存在"; }else{ echo "不存在"; //判断结果集的行数 if(mysql_num_rows($result)>0){ //将结果集放到数组$rows while($rows = mysql_fetch_assoc($result)){ echo $rows["stuName"]." ".$rows["stuAge"]; } } } mysql_close($conn); ?>
console.log(1); setTimeout(function(){ console.log(2); //异步代码后执行 },100); setTimeout(function(){ console.log(3); },200); setTimeout(function(){ console.log(4); },20); console.log(5); //1 5 4 2 3 let time=setTimeout(function(){ //同步代码 console.log(1); //异步代码 },200); clearTimeout(time); //同步代码 // 异步代码直接没有执行
ajax
1.概念
是指一种创建异步交互式网页应用的网页开发技术。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
前端通过与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
不用加载整个网页面,能够局部更新网页的技术
-
为什么要使用AJAX
* 更自然、流畅的用户体验,对用户的操作即时响应
* 在不中断用户操作的情况下与Web服务器进行通信
* 更灵敏的响应用户访问,实现近似于桌面应用程序的交互效果
* 通过局部更新页面降低网络流量,提高网络的使用效率
ajax步骤
1.创建XMLHttpRequest对象
let xhr=new XMLHttpRequest();
2.调用open方法
xhr.open("请求的方式get/post","请求的地址",true);
3.调用send方法
xhr.send();
4.onreadystatechange事件
xhr.onreadystatechange=function()
5.返回值---->xhr.responseText fun(xhr.responseText);
ajax的编写步骤-->打电话 // 1.掏手机--->创建XMLHttpRequest对象 let xhr=new XMLHttpRequest(); // 2.拨号--->调用open方法 // xhr.open("请求的方式get/post","请求的地址",true); xhr.open("get","4.ajaxStep.txt",true); // 3.发射-->调用send方法 xhr.send(); // 4.等待接通--->onreadystatechanges事件 xhr.onreadystatechange=function(){ // xhr.status==200等价于电话接通,(客户端请求成功) // xhr.readyState==4等价于接电话了 if(xhr.status==200 && xhr.readyState==4){ // 5.返回值---->xhr.responseText fun(xhr.responseText); } } console.log(xhr.responseText); function fun(resText){ let oSpan=document.querySelector("span"); oSpan.innerHTML=resText; =================== 注意:get的传参方式:url?key1=value1&key2=value2...
<?php header("Content-type:text/html;charset=utf-8"); $name=$_GET["userName"]; $conn=mysql_connect("localhost","root","root"); // echo在参与ajax的PHP文件中,echo是返回responseText的关键字 mysql_select_db("db2021"); $result=mysql_query("select * from student where stuName='$name'",$conn); if(mysql_num_rows($result)==1){ echo "用户名已存在"; }else{ echo "可以注册"; } mysql_close($conn); ?> ============== 注意: echo在参与ajax的PHP文件中,echo是返回responseText的关键字
ajax里xhr的相关属性
xhr对象的属性
-
数据的发送
get:send(无参) post:send(key1=value1&key2value2...)
xhr.send([参数]);
请求方式为get时,xhr.send()方法无参; =================== 请求方式为post时,xhr.send(key1=value1&key2value2...)有参 post传参: 1.open方法后设置请求头,将参数以form表单的方式发送 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 2.将真正的请求参数传入send // key1=value1&key2=value2...
-
onreadystatechange:
readyState的状态码发生改变,触发该事件只有2,3,4的状态码会发生改变
-
readyState:xhr对象的状态码
0:new了一个对象 1:调用完open方法 2:调用send方法,数据发送了出去 3:数据发送到了服务器 4:服务器解析完成,返回响应 所以readystate==4才能接收响应
-
responseText:返回的响应内容
-
status:代表http协议是否流畅
xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200) { console.log(xhr.readyState); } }
ajax返回Json对象
json_encode将数组转换为JSON字符串
<script> let xhr=new XMLHttpRequest(); xhr.open("get","3.ajaxReturnJson.php",true); xhr.send(); xhr.onreadystatechange=function(){ if(xhr.status==200 && xhr.readyState==4){ fun(xhr.responseText); } } function fun(resText){ //字符串转为JSON对象 let json=JSON.parse(resText); for(let index in json){ console.log(json[index]); } } </script>
<?php header("Content-type:text/html;charset=utf-8"); // 方法一:直接通过JSON字符串返回 // echo'{"name":"laowang","age":18}'; // 方法二:通过PHP的数组返回 $arr=["name"=>"laowang","age"=>6]; // json_encode将数组转换为JSON字符串 echo json_encode($arr); //laowang //18 ?>
ajax的封装
// 功能:发送请求,接收响应 // 参数: // type:get/post支持大小写 // url:服务器地址 // isAsyn:是否异步 // data:请求参数 // callBack:接收响应的回调函数 function ajaxFun(type,url,isAsyn,data,callBack){ let xhr=new XMLHttpRequest(); type=type.toLowerCase(); //转为小写 if(type=="get"){ let urlParams=url; if(data!=""){ urlParams+="?"+data; //字符串拼接 //get传参方式 } xhr.open(type,urlParams,isAsyn); xhr.send(); }else if(type=="post"){ xhr.open(type,url,isAsyn); xhr.setRequestHeader("Content-type","application/x-www/form-urlencoded"); xhr.send(data); //post传,send方法有参数,加申请头 }else{ console.log("类型错误"); } // 4.状态码事件 xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200){ callBack(xhr.responseText); } } }
promise
-
promise作用:将函数嵌套调用的方式,改为平级调用,避免回调地狱问题。
换而言之,功能未发生改变,换种语法传递回调函数。
-
promise语法:
1.promise是一个对象
2.promise通常放在一个函数体内
3.将promise对象作为函数的返回值返回
then是promise对象的一个方法
通过then方法把原来的回调函数传进去
Promise对象.then(callBack1,[callBack2]);
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html> <script> // 回调地狱 // function f1(f){ // console.log("f1"); // f(); //f==f2 f()==f2 // } // function f2(f){ // console.log("f2"); // f(); // } // function f3(f){ // console.log("f3"); // f(); // } // function f4(){ // console.log("f4"); // } //嵌套调用 //注意事项:今天千万不要研究这个 // f1(function() { // f2(function() { // f3(f4); // }); // }); //------------------------------------------------ // promise作用:将函数嵌套调用的方式,改为平级调用,避免回调地狱问题。 // 换而言之,功能未发生改变,换种语法传递回调函数。 // promise语法: // 1.promise是一个对象 // 2.promise通常放在一个函数体内 // 3.将promise对象作为函数的返回值返回 function f1() { console.log("f1"); let p = new Promise(function(callBack1) { callBack1(); }); return p; } function f2() { console.log("f2"); let p = new Promise(function(callBack1) { callBack1(); }); return p; } function f3() { console.log("f3"); let p = new Promise(function(callBack1) { callBack1(); }); return p; } function f4() { console.log("f4"); } // then是promise对象的一个方法 // 通过then方法把原来的回调函数传进去 // Promise对象.then(callBack1,[callBack2]); f1().then(f2).then(f3).then(f4); //f1(f2); </script>
第二阶段
JavaScript基础语法
-
-
HTML
:标记语言 -
JavaScript
:编程语言 -
和
css
一样,我们的js
也可以有多种方式书写在页面上让其生效 -
js
也有多种方式书写,分为 行内式, 内嵌式,外链式 -
写在标签上的 js 代码需要依靠事件(行为)来触发
-
内嵌式的 js 代码会在页面打开的时候直接触发
-
外链式 js 代码只要引入了 html 页面,就会在页面打开的时候直接触发
-
新建一个
.js
后缀的文件,在文件内书写 js 代码,把写好的 js 文件引入 html 页面 -
学习一个语言,先学习一个语言的注释,因为注释是给我们自己看的,也是给开发人员看的
-
写好一个注释,有利于我们以后阅读代码
-
一般就是用来描述下面一行代码的作用
-
可以直接写两个
/
,也可以按ctrl + /
-
一般用来写一大段话,或者注释一段代码
-
可以直接写
/**/
然后在两个星号中间写注释,也可以按shift + alt + a
-
变量指的是在程序中保存数据的一个容器
-
变量是计算机内存中存储数据的标识符,根据变量名称可以获取到内存中存储的数据
-
语法: `var 变量名 = 值
-
注意:
-
一个变量名只能存储一个值
-
当再次给一个变量赋值的时候,前面一次的值就没有了
-
变量名称区分大小写(JS 区分大小写)
-
-
规则: 必须遵守的,不遵守就是错
-
一个变量名称可以由 数字、字母、英文下划线(_)、美元符号($) 组成
-
严格区分大小写
-
不能由数字开头,不要使用中文汉字命名
-
不能是 保留字 或者 关键字
-
不要出现空格
-
-
规范: 建议遵守的(开发者默认),不遵守不会报错
-
见名识意(语义化)
-
遵循驼峰命名规则,由多个单词组成的时候,从第二个单词开始首字母大写
-
-
是指我们存储在内存中的数据的类型
-
我们通常分为两大类 基本数据类型 和 复杂数据类型
-
数值类型(number)
-
一切数字都是数值类型(包括二进制,十进制,十六进制等)
-
NaN(not a number),一个非数字
-
-
字符串类型(string)
-
被引号包裹的所有内容(可以是单引号也可以是双引号)
-
-
布尔类型(boolean)
-
只有两个(true 或者 false)
-
-
undefined类型(undefined)
-
只有一个,就是 undefined,表示没有值的意思
-
-
null类型(null)
-
只有一个,就是 null,表示空的意思
-
-
对象类型(object)
-
函数类型(function)
-
。。。
-
使用
typeof
关键字来进行判断 -
可以使用
isNaN
这个方法来判断一个变量是否为非数字isNaN检测是否为非数字
-
isNaN
:is not a number -
数据类型之间的转换,比如数字转成字符串,字符串转成布尔,布尔转成数字等
-
Number(变量)
(只能将纯数字的字符串转为数字类型)
-
可以把一个变量强制转换成数值类型
-
可以转换布尔值,将true转为1,false转为0,转换不成功的是NaN
-
遇到不可转换的都会返回 NaN
-
-
parseInt(变量)
( 将数字开头的字符串转为整数类型)
-
从第一位开始检查,是数字就转换,知道一个不是数字的内容
-
开头就不是数字,那么直接返回 NaN
-
不认识小数点,只能保留整数
-
-
parseFloat(变量)
( 将数字开头的字符串转为小数类型)
-
从第一位开始检查,是数字就转换,知道一个不是数字的内容
-
开头就不是数字,那么直接返回 NaN
-
小数全保留
-
-
除了加法以外的数学运算(隐式转换:正号,-*/%)
-
运算符两边都是可运算数字才行
-
如果运算符任何一边不是一个可运算数字,那么就会返回 NaN
-
加法不可以用
( NaN的出现:转换数字类型,数值类型转换不成功就是NaN)
-
-
变量.toString()
-
有一些数据类型不能使用
toString()
方法,比如 undefined 和 null
-
-
String(变量)
-
所有数据类型都可以
-
-
使用加法运算
-
在 JS 里面,
+
由两个含义 -
字符串拼接: 只要
+
的 任意一边是字符串,就会进行字符串拼接 -
加法运算:只有
+
两边都是数字的时候,才会进行数学运算var x = 10; //number 隐式转换转为字符: console.log(x+'') //10 console.log(''+x) //10 全为数字时进行计算: console.log(10+10+x) //30 字符串的拼接:前有数字,先进行计算再进行拼接 console.log(10+10+""+x); //20+''+10='20'+10=2010 console.log(10+10+""+10+x); //20+""+10+10='20'+10+10='2010'+10='201010'
-
-
Boolean(变量)
-
在 js 中,只有
''
、0
、null
、undefined
、NaN
,这些是 false,其余都是 true
-
-
就是在代码里面进行运算的时候使用的符号,不光只是数学运算,我们在 js 里面还有很多的运算方式
算术运算符:+ - * / % 赋值运算符: = += -= *= /= %= 比较运算符(关系运算符):> < >= <= == === != 比较的结果是一个布尔类型 !!!注: == 比较值,不比较类型(隐式转换) '1' == 1 '2' < 19(一个数字和一个字符串,在进行比较时,会进行隐式转换)
-
+
-
只有符号两边都是数字类型的时候才会进行加法运算
-
只要符号任意一边是字符串类型,就会进行字符串拼接
-
-
-
* / %-
会执行减法/乘法/除法/除法运算
-
会自动把两边都转换成数字进行运算
-
-
=
-
就是把
=
右边的赋值给等号左边的变量名 -
var num = 100
-
-
+=
var a = 10; a += 10; console.log(a); //=> 20
-
a += 10
等价于a = a + 10
-
-
-=
var a = 10; a -= 10; console.log(a); //=> 0
-
a -= 10
等价于a = a - 10
-
-
*=
var a = 10; a *= 10; console.log(a); //=> 100
-
a *= 10
等价于a = a * 10
-
-
/+
var a = 10; a /= 10; console.log(a); //=> 1
-
a /= 10
等价于a = a / 10
-
-
%=
var a = 10; a %= 10; console.log(a); //=> 0
-
a %= 10
等价于a = a % 10
-
-
==
-
比较符号两边的值是否相等,不管数据类型
-
1 == '1'
-
两个的值是一样的,所以得到 true
-
-
===
-
比较符号两边的值和数据类型是否都相等
-
1 === '1'
-
两个值虽然一样,但是因为数据类型不一样,所以得到 false
-
-
!=
-
比较符号两边的值是否不等
-
1 != '1'
-
因为两边的值是相等的,所以比较他们不等的时候得到 false
-
-
!==
-
比较符号两边的数据类型和值是否不等
-
1 !== '1'
-
因为两边的数据类型确实不一样,所以得到 true
-
-
>=
-
比较左边的值是否 大于或等于 右边的值
-
1 >= 1
true
-
-
<=
-
比较左边的值是否 小于或等于 右边的值
-
1 <= 0
false
-
-
>
-
比较左边的值是否 大于 右边的值
-
1 > 0
true -
字符串的比较:ASCII表进行,字符,字符对应的码值(数字)
-
-
<
-
比较左边的值是否 小于 右边的值
-
1 < 2
true
-
-
&&
-
进行 且 的运算
-
一假即假
-
true && true
true -
true && false
false
-
-
||
-
进行 或 的运算
-
一真即真
-
true || true
true -
false || false
false
-
-
!
当项目的需求表示不出来,但是对立面可以表示出来,就可以用取反.
例如: 求平年,不是闰年就是平年,闰年取反就是平年.
-
进行 取反 运算
-
本身是 true 的,会变成 false
-
本身是 false 的,会变成 true
-
!true
false -
!false
true
-
-
++
-
进行自增运算
-
分成两种,前置++ 和 后置++
-
前置++,会先把值自动 +1,在返回
var a = 10; console.log(++a); // 会返回 11,并且把 a 的值变成 11 ++x 先加1后操作,前加一,加完再进行其他操作.
-
后置++,会先把值返回,在自动+1
var a = 10; console.log(a++); // 会返回 10,然后把 a 的值变成 11 x++ 先操作(运算,赋值,输出)再加1
-
-
--
-
进行自减运算
-
分成两种,前置-- 和 后置--
-
和
++
运算符道理一样
-
-
分支结构
由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果
JS 语言提供了两种分支结构语句:if 语句、switch 语句
-
if 语句
-
语法结构
// 条件成立执行代码,否则什么也不做 if (条件表达式) { // 条件成立执行的代码语句 }
语句可以理解为一个行为,循环语句和分支语句就是典型的语句。一个程序由很多个语句组成,一般情况下,会分割成一个一个的语句。
-
-
if else语句(双分支语句)
-
语法结构
// 条件成立 执行 if 里面代码,否则执行else 里面的代码 if (条件表达式) { // [如果] 条件成立执行的代码 } else { // [否则] 执行的代码 }
-
执行流程
-
-
if else if 语句(多分支语句)
-
语法结构
// 适合于检查多重条件。 if (条件表达式1) { 语句1; } else if (条件表达式2) { 语句2; } else if (条件表达式3) { 语句3; .... } else { // 上述条件都不成立执行此处代码 }
-
执行逻辑
-
-
我们的 js 代码都是顺序执行的(从上到下)
-
逻辑分支就是根据我们设定好的条件来决定要不要执行某些代码
-
通过一个 if 语句来决定代码执行与否
-
语法:
if (条件) { 要执行的代码 }
-
通过
()
里面的条件是否成立来决定{}
里面的代码是否执行// 条件为 true 的时候执行 {} 里面的代码 if (true) { alert('因为条件是 true,我会执行') } // 条件为 false 的时候不执行 {} 里面的代码 if (false) { alert('因为条件是 false,我不会执行') } 注意:if的括号内部隐式调用了Boolan() if(Boolean(x)){ }
-
通过 if 条件来决定,执行哪一个
{}
里面的代码 -
语法:
if (条件) { 条件为 true 的时候执行 } else { 条件为 false 的时候执行 }
-
两个
{}
内的代码一定有一个会执行// 条件为 true 的时候,会执行 if 后面的 {} if (true) { alert('因为条件是 true,我会执行') } else { alert('因为条件是 true,我不会执行') } // 条件为 false 的时候,会执行 else 后面的 {} if (false) { alert('因为条件为 false,我不会执行') } else { alert('因为条件为 false,我会执行') }
-
可以通过 if 和 else if 来设置多个条件进行判断
-
语法:
if (条件1) { 条件1为 true 的时候执行 } else if (条件2) { 条件2为 true 的时候执行 }
-
会从头开始依次判断条件
-
如果第一个条件为 true 了,那么就会执行后面的
{}
里面的内容 -
如果第一个条件为 false,那么就会判断第二个条件,依次类推
-
-
多个
{}
,只会有一个被执行,一旦有一个条件为 true 了,后面的就不在判断了// 第一个条件为 true,第二个条件为 false,最终会打印 “我是代码段1” if (true) { alert('我是代码段1') } else if (false) { alert('我是代码段2') } // 第一个条件为 true,第二个条件为 true,最终会打印 “我是代码段1” // 因为只要前面有一个条件满足了,就不会继续判断了 if (true) { alert('我是代码段1') } else if (true) { alert('我是代码段2') } // 第一个条件为 false,第二个条件为 true,最终会打印 “我是代码段2” // 只有前一个条件为 false 的时候才会继续向后判断 if (false) { alert('我是代码段1') } else if (true) { alert('我是代码段2') } // 第一个条件为 false,第二个条件为 false,最终什么也不会发生 // 因为当所有条件都为 false 的时候,两个 {} 里面的代码都不会执行 if (false) { alert('我是代码段1') } else if (false) { alert('我是代码段2') }
-
和之前的
if else if ...
基本一致,只不过是在所有条件都不满足的时候,执行最后 else 后面的{}
// 第一个条件为 false,第二个条件为 false,最终会打印 “我是代码段3” // 只有前面所有的条件都不满足的时候会执行 else 后面的 {} 里面的代码 // 只要前面有一个条件满足了,那么后面的就都不会执行了 if (false) { alert('我是代码段1') } else if (false) { alert('我是代码段2') } else { alert('我是代码段3') }
-
也是条件判断语句的一种
switch语句执行效率高于if多分支,if多分支运用场景比switch多
-
是对于某一个变量的判断
-
语法:
switch (要判断的变量) { case 情况1: 情况1要执行的代码 break case 情况2: 情况2要执行的代码 break case 情况3: 情况3要执行的代码 break default: 上述情况都不满足的时候执行的代码 }
-
要判断某一个变量 等于 某一个值得时候使用
-
-
例子🌰: 根据变量给出的数字显示是星期几
var week = 1 switch (week) { case 1: alert('星期一') break case 2: alert('星期二') break case 3: alert('星期三') break case 4: alert('星期四') break case 5: alert('星期五') break case 6: alert('星期六') break case 7: alert('星期日') break default: alert('请输入一个 1 ~ 7 之间的数字') }
-
三元运算,就是用 两个符号 组成一个语句
-
三元运算只是对 if else 语句的一个简写形式
-
语法:
条件 ? 条件为 true 的时候执行 : 条件为 false 的时候执行
表达式:是一个式子(得到一个值)或者一个值; 三元运算符的结构: // 条件表达式? 表达式1:表达式2 // 条件表达式结果为true,得到表达式1;为false,得到为表达式2 var age = 18; age >= 18 ? alert('已经成年') : alert('没有成年')
-
循环结构,就是根据某些给出的条件,重复的执行同一段代码
-
循环必须要有某些固定的内容组成
-
初始化
-
条件判断
-
要执行的代码
-
自身改变
-
-
循环分为三种:for循环,while循环,do while循环
-
while
, 当…时,其实就是当条件满足时就执行代码,一旦不满足了就不执行了 -
语法
while (条件) { 满足条件就执行 }
-
因为满足条件就执行,所以我们写的时候一定要注意,就是设定一个边界值,不然就一直循环下去了
初始化变量; while(条件表达式){ 语句体; 自增自减表达式; } // 1. 初始化条件 var num = 0; // 2. 条件判断 while (num < 10) { // 3. 要执行的代码 console.log('当前的 num 的值是 ' + num) // 4. 自身改变 num = num + 1 }
-
如果没有自身改变,那么就会一直循环不停了
-
-
是一个和
while
循环类似的循环 -
while
会先进行条件判断,满足就执行,不满足直接就不执行了 -
但是
do while
循环是,先不管条件,先执行一回,然后在开始进行条件判断 -
语法:
do { 要执行的代码 } while (条件)
初始化变量; do{ 循环体; 自增自减表达式 }while(条件表达式); // 下面这个代码,条件一开始就不满足,但是依旧会执行一次 do 后面 {} 内部的代码 var num = 10 do { console.log('我执行了一次') num = num + 1 } while (num < 10)
-
和
while
和do while
循环都不太一样的一种循环结构 -
道理是和其他两种一样的,都是循环执行代码的
-
语法:
for (var i = 0; i < 10; i++) { 要执行的代码 }
for(初始化语句;条件表达式;自增自减表达式){} 或者 for(初始化语句;条件表达式;操作表达式){} // 把初始化,条件判断,自身改变,写在了一起 for (var i = 1; i <= 10; i++) { // 这里写的是要执行的代码 console.log(i) } // 控制台会依次输出 1 ~ 10
-
这个只是看起来不太舒服,但是用起来比较好用
-
在循环没有进行完毕的时候,因为我设置的条件满足,提前终止循环
-
比如:我要吃五个包子,吃到三个的时候,不能在吃了,我就停止吃包子这个事情
-
要终止循环,就可以直接使用
break
关键字break :中止当前(本层)循环,不再循环 for (var i = 1; i <= 5; i++) { // 每循环一次,吃一个包子 console.log('我吃了一个包子') // 当 i 的值为 3 的时候,条件为 true,执行 {} 里面的代码终止循环 // 循环就不会继续向下执行了,也就没有 4 和 5 了 if (i === 3) { break } }
-
在循环中,把循环的本次跳过去,继续执行后续的循环
-
比如:吃五个包子,到第三个的时候,第三个掉地下了,不吃了,跳过第三个,继续吃第四个和第五个
-
跳过本次循环,就可以使用
continue
关键字continue:中止本次循环,继续下一次循环 for (var i = 1; i <= 5; i++) { // 当 i 的值为 3 的时候,执行 {} 里面的代码 // {} 里面有 continue,那么本次循环后面的代码就都不执行了 // 自动算作 i 为 3 的这一次结束了,去继续执行 i = 4 的那次循环了 if (i === 3) { console.log('这个是第三个包子,掉地下了,我不吃了') continue } console.log('我吃了一个包子') }
函数
函数的概念
函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。
先看一段代码 // eg:以前写的一段代码 for (var i = 0; i < 10; i++) { console.log(i) } // 函数,这个 {} 就是那个 “盒子” function fn() { // 这个函数我们以前写的代码 for (var i = 0; i < 10; i++) { console.log(i) } }
函数的两个阶段(重点)
-
按照我们刚才的说法,两个阶段就是 放在盒子里面 和 让盒子里面的代码执行
函数定义阶段
-
定义阶段就是我们把代码 放在盒子里面
-
我们就要学习怎么 放进去,也就是书写一个函数
-
我们有两种定义方式 声明式 和 赋值式(函数表达式)
函数的声明
// 声明函数 function 函数名() { //函数体代码 }
-
function 是声明函数的关键字,必须小写
-
由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名命名为动词,比如 getSum
代码展示如下
//声明一个名为和helloWord的函数 function helloWord() { console.log('hi~~'); }
赋值式
又称为函数表达式
-
其实就是和我们使用
var
关键字是一个道理了 -
首先使用
var
定义一个变量,把一个函数当作值直接赋值给这个变量就可以了 -
语法:
2. 函数表达式(赋值式) var 函数名 = function(){} var fn = function () { // 一段代码 } // 不需要在 function 后面书写函数的名字了,因为在前面已经有了
函数调用阶段
-
就是让 盒子里面 的代码执行一下
-
让函数执行
-
两种定义函数的方式不同,但是调用函数的方式都以一样的
调用一个函数
// 调用函数 函数名(); // 通过调用函数名来执行函数体代码
-
调用的时候千万不要忘记添加小括号
-
口诀:函数不调用,自己不执行
-
注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。
代码如下
//调用helloWord函数 helloWord();
调用上的区别
-
虽然两种定义方式的调用都是一样的,但是还是有一些区别的
-
声明式函数: 调用可以在 定义之前或者定义之后
// 可以调用 fn() // 声明式函数 function fn() { console.log('我是 fn 函数') } // 可以调用 fn()
-
赋值式函数: 调用只能在 定义之后
// 会报错 fn() // 赋值式函数 var fn = function () { console.log('我是 fn 函数') } // 可以调用 fn()
函数的参数(重点)
-
函数参数语法
形参:函数定义时设置接收调用时传入
实参:函数调用时传入小括号内的真实数据
-
参数分为两种 行参 和 实参(形参是形式参数,实参是实际参数,实参的值会赋值给形参)
// 声明式 function fn(行参写在这里) { // 一段代码 } fn(实参写在这里) // 赋值式函数 var fn = function (行参写在这里) { // 一段代码 } fn(实参写在这里)
行参和实参的作用
参数的作用 : 在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。
函数参数的运用:
// 带参数的函数声明 function 函数名(形参1, 形参2 , 形参3...) { // 可以定义任意多的参数,用逗号分隔 // 函数体 } // 带参数的函数调用 函数名(实参1, 实参2, 实参3...);
1.调用的时候实参值是传递给形参的
2.形参简单理解为:不用声明的变量
3.实参和形参的多个参数之间用逗号(,)分隔
-
函数形参和实参数量不匹配时
注意:在JavaScript中,形参的默认值是undefined。
小结:
-
函数可以带参数也可以不带参数
-
声明函数的时候,函数名括号里面的是形参,形参的默认值为 undefined
-
调用函数的时候,函数名括号里面的是实参
-
多个参数中间用逗号分隔
-
形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配
// 书写一个参数 function fn(num) { // 在函数内部就可以使用 num 这个变量 } var fn1 = function (num) { // 在函数内部就可以使用 num 这个变量 } // 书写两个参数 function fun(num1, num2) { // 在函数内部就可以使用 num1 和 num2 这两个变量 } var fun1 = function (num1, num2) { // 在函数内部就可以使用 num1 和 num2 这两个变量 }
-
行参的值是在函数调用的时候由实参决定的
-
实参
-
在函数调用的时候给行参赋值的(调用函数参数叫实参)
-
也就是说,在调用的时候是给一个实际的内容的
function fn(num) { // 函数内部可以使用 num } // 这个函数的本次调用,书写的实参是 100 // 那么本次调用的时候函数内部的 num 就是 100 fn(100) // 这个函数的本次调用,书写的实参是 200 // 那么本次调用的时候函数内部的 num 就是 200 fn(200)
-
函数内部的行参的值,由函数调用的时候传递的实参决定( 函数调用的过程:实际上就是把实参传递给形参)
-
多个参数的时候,是按照顺序一一对应的
function fn(num1, num2) { // 函数内部可以使用 num1 和 num2 } // 函数本次调用的时候,书写的参数是 100 和 200 // 那么本次调用的时候,函数内部的 num1 就是 100,num2 就是 200 fn(100, 200)
-
参数个数的关系
-
行参比实参少
-
因为是按照顺序一一对应的
-
行参少就会拿不到实参给的值,所以在函数内部就没有办法用到这个值
function fn(num1, num2) { // 函数内部可以使用 num1 和 num2 } // 本次调用的时候,传递了两个实参,100 200 和 300 // 100 对应了 num1,200 对应了 num2,300 没有对应的变量 // 所以在函数内部就没有办法依靠变量来使用 300 这个值 fn(100, 200, 300)
-
-
行参比实参多
-
因为是按照顺序一一对应的
-
所以多出来的行参就是没有值的,就是
undefined
function fn(num1, num2, num3) { // 函数内部可以使用 num1 num2 和 num3 } // 本次调用的时候,传递了两个实参,100 和 200 // 就分别对应了 num1 和 num2 // 而 num3 没有实参和其对应,那么 num3 的值就是 undefined fn(100, 200)
-
函数的return(重点)
-
return 返回的意思,其实就是给函数一个 返回值 和 终断函数
终断函数
-
当开始执行函数以后,函数内部的代码就会从上到下的依次执行
-
必须要等到函数内的代码执行完毕
-
而
return
关键字就是可以在函数中间的位置停掉,让后面的代码不在继续执行function fn() { console.log(1) console.log(2) console.log(3) // 写了 return 以后,后面的 4 和 5 就不会继续执行了 return console.log(4) console.log(5) } // 函数调用 fn()
返回值
函数的返回值
-
return 语句
返回值:函数调用整体代表的数据;函数执行完成后可以通过return语句将指定数据返回 。
// 声明函数 function 函数名(){ ... return 需要返回的值; } // 调用函数 函数名(); // 此时调用函数就可以得到函数体内return 后面的值
1.在使用 return 语句时,函数会停止执行,并返回指定的值
2.如果函数没有 return ,返回的值是 undefined
-
break ,continue ,return 的区别
break :结束当前的循环体(如 for、while)
continue :跳出本次循环,继续执行下次循环(如 for、while)
return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码
函数带了一个叫return的关键字,函数调用完毕之后就是一个值,通过return 将函数的计算结果给带出来 // 比如 1 + 2 是一个表达式,那么 这个表达式的结果就是 3 console.log(1 + 2) // 3 function fn() { // 执行代码 } // fn() 也是一个表达式,这个表达式就没有结果出现 console.log(fn()) // undefined
-
return
关键字就是可以给函数执行完毕一个结果function fn() { // 执行代码 return 100 } // 此时,fn() 这个表达式执行完毕之后就有结果出现了 console.log(fn()) // 100
-
我们可以在函数内部使用
return
关键把任何内容当作这个函数运行后的结果 -
注意: 1.声明的求和和求个数的变量放在for循环的外部 2. return 放在函数的结尾处,不要放在循环内部 3. 函数内部定义的变量,外部访问不到 4. 函数调用的(值)结果就是return 的结果 5. return 终止函数,return语句以后的代码不会被执行 6.如果一个函数没有带return ,默认返回的是undefined
-
函数返回值注意事项
-
return 终止函数
function getSum(num1, num2) { return num1 + num2; // return 后面的代码不会被执行 alert('我是不会被执行的哦!') }
-
return 只能返回一个值
function fn(num1, num2) { return num1, num2; // 返回的结果是最后一个值 }
-
函数如果有return,则返回的是return后面的值;如果函数没有return,则返回undefined
function fun1() { return 666; } console.log(fun1()); // 返回 666 function fun2() { } console.log(fun2()); // 函数返回的结果是 undefined
##
函数的优点
-
函数就是对一段代码的封装,在我们想调用的时候调用
-
函数的几个优点
-
封装代码,使代码更加简洁
-
复用,在重复功能的时候直接调用就好
-
代码执行时机,随时可以在我们想要执行的时候执行
-
arguments的使用
arguments的使用
当不确定有多少个参数传递的时候,可以用 arguments 来获取。JavaScript 中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
-
具有 length 属性
-
按索引方式储存数据
-
不具有数组的 push , pop 等方法
注意:在函数内部使用该对象,用此对象获取函数调用时传的实参。
代码展示如下
function fn() { for (var i = 0; i < arguments.length; i++) { console.log(arguments[i]); } } fn(1, 2, 3); fn(1, 2, 3, 4, 5);
####
预解析(重点)
-
预解析 其实就是聊聊 js 代码的编译和执行
-
js 是一个解释型语言,就是在代码执行之前,先对代码进行通读和解释,然后在执行代码
-
也就是说,我们的 js 代码在运行的时候,会经历两个环节 解释代码 和 执行代码
解释代码
-
因为是在所有代码执行之前进行解释,所以叫做 预解析(预解释)
-
需要解释的内容有两个
-
声明式函数
-
在内存中先声明有一个变量名是函数名,并且这个名字代表的内容是一个函数
-
-
var
关键字-
在内存中先声明有一个变量名
-
-
-
看下面一段代码
fn() console.log(num) function fn() { console.log('我是 fn 函数') } var num = 100
-
经过预解析之后可以变形为
function fn() { console.log('我是 fn 函数') } var num fn() console.log(num) num = 100
-
赋值是函数会按照
var
关键字的规则进行预解析函数(下)
作用域(重点)
-
什么是作用域,就是一个变量可以生效的范围
-
变量不是在所有地方都可以使用的,而这个变量的使用范围就是作用域
全局作用域
-
全局作用域是最大的作用域
-
在全局作用域中定义的变量可以在任何地方使用
-
页面打开的时候,浏览器会自动给我们生成一个全局作用域 window
-
这个作用域会一直存在,直到页面关闭就销毁了
// 下面两个变量都是存在在全局作用域下面的,都是可以在任意地方使用的 var num = 100 var num2 = 200
局部作用域
-
局部作用域就是在全局作用域下面有开辟出来的一个相对小一些的作用域
-
在局部作用域中定义的变量只能在这个局部作用域内部使用
-
在 JS 中只有函数能生成一个局部作用域,别的都不行
-
每一个函数,都是一个局部作用域
// 这个 num 是一个全局作用域下的变量 在任何地方都可以使用 var num = 100 function fn() { // 下面这个变量就是一个 fn 局部作用域内部的变量 // 只能在 fn 函数内部使用 var num2 = 200 } fn()
变量的声明提升
js引擎执行代码: 先找到所有声明相关的,进行提升(声明提升) 变量提升和函数提升 变量提升只提升声明部分:var a; 函数提升,提升的是整体: function getSum(){console.log(1+2);} 如果变量提升和函数提升都存在,函数提升会在变量提升的上面 提升到当前作用域的最顶端: //未提升前: console.log(1); console.log(a); getSum(); var a = 10; console.log(2); function getSum(){ console.log(1+2); //提升后 function getSum() { console.log(1 + 2); } var a; console.log(1);//1 console.log(a); //undefined getSum(); // 3 a = 10; console.log(2);//2
变量使用规则(重点)
-
有了作用域以后,变量就有了使用范围,也就有了使用规则
-
变量使用规则分为两种,访问规则 和 赋值规则
访问规则
-
当我想获取一个变量的值的时候,我们管这个行为叫做 访问
-
获取变量的规则:
-
首先,在自己的作用域内部查找,如果有,就直接拿来使用
-
如果没有,就去上一级作用域查找,如果有,就拿来使用
-
如果没有,就继续去上一级作用域查找,依次类推
-
如果一直到全局作用域都没有这个变量,那么就会直接报错(该变量 is not defined)
var num = 100 function fn() { var num2 = 200 function fun() { var num3 = 300 console.log(num3) // 自己作用域内有,拿过来用 console.log(num2) // 自己作用域内没有,就去上一级,就是 fn 的作用域里面找,发现有,拿过来用 console.log(num) // 自己这没有,去上一级 fn 那里也没有,再上一级到全局作用域,发现有,直接用 console.log(a) // 自己没有,一级一级找上去到全局都没有,就会报错 } fun() } fn()
-
-
变量的访问规则 也叫做 作用域的查找机制
-
作用域的查找机制只能是向上找,不能向下找
function fn() { var num = 100 } fn() console.log(num) // 发现自己作用域没有,自己就是全局作用域,没有再上一级了,直接报错
赋值规则
-
当你想给一个变量赋值的时候,那么就先要找到这个变量,在给他赋值
-
变量赋值规则:
-
先在自己作用域内部查找,有就直接赋值
-
没有就去上一级作用域内部查找,有就直接赋值
-
在没有再去上一级作用域查找,有就直接赋值
-
如果一直找到全局作用域都没有,那么就把这个变量定义为全局变量,在给他赋值
function fn() { num = 100 } fn() // fn 调用以后,要给 num 赋值 // 查看自己的作用域内部没有 num 变量 // 就会向上一级查找 // 上一级就是全局作用域,发现依旧没有 // 那么就会把 num 定义为全局的变量,并为其赋值 // 所以 fn() 以后,全局就有了一个变量叫做 num 并且值是 100 console.log(num) // 100
-
递归函数
-
什么是递归函数
-
在编程世界里面,递归就是一个自己调用自己的手段
-
递归函数: 一个函数内部,调用了自己,循环往复
// 下面这个代码就是一个最简单的递归函数 // 在函数内部调用了自己,函数一执行,就调用自己一次,在调用再执行,循环往复,没有止尽 function fn() { fn() } fn()
-
其实递归函数和循环很类似
-
需要有初始化,自增,执行代码,条件判断的,不然就是一个没有尽头的递归函数,我们叫做 死递归
简单实现一个递归
-
我们先在用递归函数简单实现一个效果
-
需求: 求 1 至 5 的和
-
先算 1 + 2 得 3
-
再算 3 + 3 得 6
-
再算 6 + 4 得 10
-
再算 10 + 5 得 15
-
结束
-
-
开始书写,写递归函数先要写结束条件(为了避免出现 “死递归”)
function add(n) { // 传递进来的是 1 // 当 n === 5 的时候要结束 if (n === 5) { return 5 } } add(1)
-
再写不满足条件的时候我们的递归处理
function add(n) { // 传递进来的是 1 // 当 n === 5 的时候要结束 if (n === 5) { return 5 } else { // 不满足条件的时候,就是当前数字 + 比自己大 1 的数字 return n + add(n + 1) } } add(1)
简单了解对象
-
对象是一个复杂数据类型
-
其实说是复杂,但是没有很复杂,只不过是存储了一些基本数据类型的一个集合
var obj = { num: 100, str: 'hello world', boo: true}
-
这里的
{}
和函数中的{}
不一样 -
函数里面的是写代码的,而对象里面是写一些数据的
-
对象就是一个键值对的集合
-
{}
里面的每一个键都是一个成员 -
也就是说,我们可以把一些数据放在一个对象里面,那么他们就互不干扰了
-
其实就是我们准备一个房子,把我们想要的数据放进去,然后把房子的地址给到变量名,当我们需要某一个数据的时候,就可以根据变量名里面存储的地址找到对应的房子,然后去房子里面找到对应的数据
创建一个对象
-
字面量的方式创建一个对象
// 创建一个空对象var obj = {}// 像对象中添加成员obj.name = 'Jack'obj.age = 18
-
内置构造函数的方式创建对象
// 创建一个空对象var obj = new Object()// 向对象中添加成员obj.name = 'Rose'obj.age = 20
-
Object 是 js 内置给我们的构造函数,用于创建一个对象使用的
-
数组
数组的概念
一个变量只能存储一个数据,如果我们有一组数据,比如1到100一百个数字,定义100个变量来存储就太痛苦了,这时候我们就需要数组来存储这样的数据。数组:存储一组数据.
数组的定义
数组为引用类型,创建时可通过构造方法创建。
堆和栈及索引思维
构造方法
1.无参构造函数,创建一空数组
var a1=new Array();
2.一个数字参数构造函数,指定数组长度(由于数组长度可以动态调整,作用并不大),创建指定长度的数组
var a2=new Array(5);
3.带有初始化数据的构造函数,创建数组并初始化参数数据
var a3=new Array(4,'hello',2.34);
数组的定义 1.构造方法 new:在堆内开辟空间的关键词 Array:数组数据类型 var arr=new Array(1,2,3,4,5,6);
字面量
4.使用方括号,创建空数组,等同于调用无参构造函数
var a4=[];
5.使用中括号,并传入初始化数据,等同于调用调用带有初始化数据的构造函数
var a5=[10];
var arr=[1,2,3,4,5,6,7,8,9]; 最常用的
数据类型分类
内置基本类型: Number String Boolean undefined null 引用类型: object 内置类型与引用类型的区别: 内置类型:只有一块空间,在栈区,该空间直接保存着变量的数值 引用类型: 有两块空间,一块栈空间,存储new出来堆空间的地址, 另一块堆空间,存储真正的数值
数组元素的访问
数组名[下标]; 下标:索引,从零开始连续的自然数,基于0; 下标也可以是变量 数组下标的取值范围0~元素个数-1; 数组的长度:length 注意事项: 数组的下标不能越界访问 超出范围出现undefined,不报错, 数组的长度 length console.log(arr.length); 数组的遍历 var arr=[7,8,9,6,5,0,1,2,3]; for(var i=0;i<arr.length;i++){ document.write(arr3[i]+" "); } 数组的逆序: 思想:相当于第一个和最后一个交换,第二个和倒数第二个交换,交换的次数为数组元素个数的一半 交换需要中间变量 程序=算法+语法 算法:先用中文描述出来问题解决的步骤,然后再翻译为JS语言 var t=0;//定义中间变量 var arr=[7,8,9,6,5,1,2,3]; for(var i=0;i<arr.length/2;i++){ t=arr[i]; arr[i]=arr[arr.length-1-i]; arr[arr.length-1-i]=t; } document.write(arr+" "); 分析:7和3交换 规律:arr4[0]和arr4[arr4.length-1-0]交换 以此类推
数组的相关函数
函数需要注意的几个点:功能 ,参数 ,返回值 eg: 封装闰年问题 function getRn(x){ if(x%4==0&&x%100!=0 ||x%400==0){ return true; }else{ return false; } } if(getRn(2008)==true){ console.log('闰年'); }else{ console.log('平年'); }
-
push尾插 (尾插有参返新长)
功能:末尾插入一个或多个元素 参数:push(x1,[x2,x3])必须要有一个参数,方括号里面表示可选的参数,可有可没有. 返回值:返回尾插后新数组的长度 var arr=[1,2,3]; var len=arr.push(4,5,6); console.log(len);//6 console.log(arr);//[1,2,3,4,5,6]
-
pop尾删
pop:尾删 参数:无 返回值:返回被删掉的元素 var arr=[4,5,7,8,5,1,2,3]; var x=arr.pop(); console.log(x,arr);//3,[4,5,7,8,5,1,2]
-
unshift头插 (头插有参返新长)
unshift:头插 功能:头部插入一个或若个元素 参数:unshift(x1,[x2,x3]) 返回值:返回头插后新数组的长度 var arr=[1,2,3]; var x=arr.unshift(4,5,6); console.log(x,arr);//6,[4,5,6,1,2,3]
-
shift 头删
shift:头删 功能:删除第一个元素 参数:无参 返回值:返回被删除的元素 var arr=[1,2,3]; var x=arr.shift(); console.log(x,arr);//1,[2,3]
-
reverse 逆序
reverse 功能:逆序 参数:无 返回值:无 直接改变原数组对象 var arr=[1,2,3,4,5,6]; arr.reverse(); console.log(arr);//[6,5,4,3,2,1]
-
splice 删除指定元素且用新的元素代替
功能:删除指定元素且用新的元素代替 参数:splice(起始位置,偏移量,[替换的元素]); 返回值:被删除的元素(其实就是一个数组) 注意:起始位置:看的下标,偏移量从下标开始算 var arr=[1,2,3,4,5,6]; var arr1=arr.splice(2,3,7,8,9); console.log(arr,arr1);//[1,2,7,8,9,6][3,4,5]
-
concat:拼接数组
功能:拼接数组 参数:concat(数组) 返回值:被拼接的新数组 var arr1=[7,8,9,5,4]; var arr2=[1,2,3,6]; var arr3=arr1.concat(arr2); console.log(arr3);//[7,8,9,5,4,1,2,3,6]
-
join 将数组转换为字符串
功能:将数组转换为字符串 参数:([字符串分隔符]),默认分隔符为逗号 返回值:被分隔的字符串 var arr=[1,2,3,4,5,6]; var arr1=arr.join('*'); console.log(arr1);// 1*2*3*4*5*6
-
-
slice 数组元素的截取
slice 功能:数组元素的截取 参数:slice(起始位置,结束位置);[左闭右开) 返回值:返回被截取的数组 var arr=[1,2,3,4,5,6]; var arr1=arr.slice(2,5); console.log(arr1);// [3,4,5]返回被截取的数组
-
sort(了解)
var arr=[7,8,9,5,1,2,3]; arr.sort(); console.log(arr);// [1, 2, 3, 5, 7, 8, 9]按照字符串的大小排序,内部Ascall码值比较 从小到大
-
多维数组
多维数组 js中多维数组是模拟一维数组的 多维数组实际是一维数组的嵌套
var arr=[ [1,2,3],//arr[0]第一个元素 [4,5],//arr[1]第二个元素 [7,8,9]//arr[2]第三个元素 ] //二维数组的遍历 for(var i=0;i<arr.length;i++){ for(var j=0;j<arr[i].length;j++){ document.write(arri+" "); } document.write(" ") }
// 冒泡排序:两两比较,每趟找出最大或者最小的一个数值 // 趟数:N-1 // 次数:N-1-i var arr=[5,6,7,4,8,3,9,2,0,1]; var t; for(var i=0;i<arr.length-1;i++){ for(var j=0;j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){ t=arr[j]; arr[j]=arr[j+1]; arr[j+1]=t;//实现交换 } } } console.log(arr); /* 5,6,7,4,8,3,9,2,0,1 初始数据 模拟第0趟比较 交换9次 5,6,7,4,8,3,9,2,0,1 5,6,7,4,8,3,9,2,0,1 5,6,4,7,8,3,9,2,0,1 5,6,4,7,8,3,9,2,0,1 5,6,4,7,3,8,9,2,0,1 5,6,4,7,3,8,9,2,0,1 5,6,4,7,3,8,2,9,0,1 5,6,4,7,3,8,2,0,9,1 5,6,4,7,3,8,2,0,1, 9 第1趟交换 交换8次 */
## 选择排序 ```+htnl var arr=[7,8,6,2,10,3]; // 核心:外层循环N-1次 // 内层:循环N-1-i次 // 思路:i控制指定位置 // k控制目标位置 // k=i;用k来查找目标位置 // 最后交换arr[k]和arr[i]; // 每趟交换一次,找到最大(最小)的数,然后放到目标位置,进行下标交换; var t,k; for(var i=0;i<arr.length-1;i++){//趟数 k=i; //控制目标位置 for(var j=i+1;j<arr.length;j++){//次数 if(arr[k]>arr[j]){ k=j; //下标交换,相当于找到目标位置,与指定位置交换下标 } }t=arr[i]; arr[i]=arr[k]; arr[k]=t; }console.log(arr);
-
-
-
-
indexOf
功能:查找目标元素,找到返回下标,找不到返回-1 参数:indexof(目标元素); 返回值:找到返回下标,找不到返回-1 注意事项:若出现重复的元素,则只能查找第一个出现的元素下标 var arr=[7,8,6,3,2,0] console.log(arr.indexOf(4));//-1,没有 案例:数组去重: 数组去重 var arr=[4,5,3,2,3,5,8,7,4,3]; var arr1=[]; for(var i=0;i<arr.length;i++){ if(arr1.indexOf(arr[i])==-1){ arr1.push((arr[i])); } }console.log(arr1);
-
forEash
功能:对数组的所有元素执行某种相同的操作 参数:forEash(回调函数) 回调函数参数:回调函数(数组元素的值,[下标,元素所在的数组]) 返回值:无 var arr=[1,2,3]; function fun(x,index,a){ a[index]+=10; } arr.forEach(fun); console.log(arr); //[11,12,13]
-
map:
功能:和forEash基本一模一样,多一个返回值 参数:map(回调函数) 回调函数参数:回调函数(数组元素的值,[下标,元素所在的数组]) 返回值:用回调函数return的数据,构成一个数组 var arr=[1,2,3]; function fun(x,index,a){ a[index]+=10; return a[index]; } var arr1=arr.map(fun); console.log(arr1); //[11,12,13]
-
filter
功能:按条件过滤元素 参数:filter(回调函数) 回调函数参数:回调函数(数组元素的值,[下标,元素所在的数组]) 返回值:根据当前回调函数return的布尔值,决定是否返回当前元素本身 var arr=[4,5,6,2,1,2,3]; function fun(x){ if(x%2==1){ return true; }else{ return false; } } var arr1=arr.filter(fun); console.log(arr1); //[5,1,3]过滤偶数
回调函数
回调函数:一个被当做参数的函数(函数调用函数) 解决问题:将自定义模块传入至第三方模块 function f1(f){//第三方代码,闭园代码 // f==f2; // f()==f2() f();//这一步是第三方调用的,和自定义模块设计无关 } var f2=function(){ //自定义模块 console.log("f2"); } f1(f2);//函数的调用 //f2
字符串
字符串的定义和创建
1.字面量 var str="heihei"//内置基本类型 console.log(typeof str); console.log(str); 2.构造方法 var str1=new String("heihei");//引用类型 console.log(typeof str1);//object console.log(str1); 结论:一般用字面量方式定义字符串
字符串的应用
ASCII码表 必须记住 97 a 65 A 48 '0' 32 空格 13 回车 注意事项:ascll码值和字符是完全等价的
字符串常见API
-
charAt
charAt 功能:查询索引对应的字符,返回字符 参数:charAt(索引) 返回值:返回索引对应的字符 var str ="adfghjk"; console.log(str.charAt(1));//d console.log(str[0]);//不建议这样写 a
-
charCodeAt
charCodeAt 功能:查询索引对应的字符,返回字符所对应的ASCLL码值 参数:charCodeAt(索引) 返回值:返回索引所对应的ASCLL码值 var str ="adfghjk"; console.log(str.charCodeAt(1));//100
-
length
var str ="adfghjk"; console.log(str.length); //7 ================== 案例: 输入字符串,统计字符串有多少个大写字母,小写字母,数字,空格,其他字符 var str = "12a45b cA AB+#$%^"; var bigChar=0; var smallChar=0; var num=0; var space=0; var other=0; for(var i=0;i<str.length;i++){ if(str.charAt(i)>'0'&&str.charAt(i)<='9'){ num++; }else if(str.charAt(i)>'a'&&str.charAt(i)<='z'){ smallChar++; }else if(str.charAt(i)>'A'&&str.charAt(i)<='Z'){ bigChar++; }else if(str.charAt(i)==' '){ space++; }else{ other++; } } console.log(num,smallChar,bigChar,other,space);//4 2 1 8 2
将ascll码值转换为字符串,返回被转换的字符 注意事项:通过String类型名来调用
将ascll码值转换为字符串,返回被转换的字符 注意事项:通过String类型名来调用 fromCharCode(asc1,[asc2,...]); console.log(String.fromCharCode(97,98)); indexOf("abc")查找字符串第一次出现的位置,返回字符串首字母的下标 var str="helloword"; console.log(str.indexOf("l"));//2 lastIndexOf("abc")查找字符串最后一次出现的位置 如果没有 返回-1 var str="helloword"; console.log(str.lastIndexf("l"));//3
-
replace
功能:用参数2替换参数1 参数:replace(参数1,参数2) 返回值:被替换的字符串 只替换第一次出现的一个 var str = "jinyan de ge bi zhu zhe jinyan"; str=str.replace("jinyan","laowang"); console.log(str); //laowang de ge bi zhu zhe jinyan
-
slice
字符串的截取 slice(起始位置,结束位置);左闭右开 substring(起始位置,结束为止);左闭右开 var str = "helloworld"; console.log(str.slice(2,5));//llo console.log(str.substring(2,5));//ll0 slice与substring区别 slice支持负数 var str = "helloworld"; console.log(str.slice(-5,-2));//wor 左开右闭
-
split
功能:字符串分隔符,将字符串转为数组 参数:split("分割字符串") 返回值:新的数组 // 从字符串shi分割开 var str = "cao bo yong shi cao bo lin de di di"; var arr=str.split('shi'); console.log(arr); // ['cao bo yong ', ' cao bo lin de di di']
-
转大小写
转小写 console.log('htiVBNM'.toLowerCase()); //htivbnm 转大写 console.log('htiVBNM'.toUpperCase()); // HTIVBNM
Math and Date 定时器
1.数学对象
数学对象 : 特点不需要定义对象实例,直接通过 Math.方法名 直接调用。
Math.方法名 直接调用
1. Math.floor(小数) 向下取整 取出小于该数的最大整数 Math.floor(4.3);// 4 Math.floor(-4.3);// -5 console.log(Math.floor(4.9));//4 与四舍五入无关 2.Math.ceil(小数) // 向上取整 取出大于该数的最小整数 console.log(Math.ceil(4.3)); //5 console.log(Math.ceil(-4.3)); // -4 3.Math.round(小数) 四舍五入 console.log(Math.round(4.1)); 4. Math.sqrt(number) 开平方根 5. Math.pow(m,n) 返回m的n次方 6. Math.min(1,-2,3,4) 取多个数最小值 7. Math.abs(number) 返回绝对值 8. Math.random() 返回0~1之间的随机数
获取任意区间值的随机函数
for(var i=0; i<50; i++){ //console.log(parseInt(Math.random()*100)%6+3);//[1,6] [2,8] //console.log(Math.round(Math.random() * 6) + 2); //[0,5] [2,8]==[min,max] console.log(rand(100,500)); } function rand(min,max){ return Math.round(Math.random() * (max-min)) + min; }
日期对象
定义: var d = new Date(); 获取时间的方法: getFullYear() //返回年份 getMonth() //返回月份值 ,从0开始 0~11 getDate() //返回日期 getDay() //返回星期几(为数字) 0~6 星期日为0 getHours() //返回小时数 getMinutes() //返回分钟数 getSeconds() //返回秒数 =========== 封装时间字符串: function dateToString(d){ var a = ["星期天","星期一","星期二","星期三","星期四","星期五","星期六",]; var _y = d.getFullYear(); var _m = d.getMonth()+1; var _d = d.getDate(); var _h = toTwo(d.getHours()); var _mm = toTwo(d.getMinutes()); var _s = toTwo(d.getSeconds()); var _w = d.getDay(); var str = _y + "年" + _m + "月" + _d + "日"; str += _h + "时" + _mm + "分" + _s + "秒" + " " + a[d.getDay()]; return str; } function toTwo(v){ return v<10?"0"+v:v; } document.write(dateToString(new Date())); console.log(d.toLocaleString()); //根据本地时间格式,把 Date 对象的日期部分转换为字符串。 字符串改为时间: 方法1: var str = "2001-8-6,18:23:56"; var bir = new Date(str); document.write(bir.getMinutes()); 方法2: Date.parse(日期字符串) //返回自1970年1月1日起至参数日期的毫秒数 var t = new Date(Date.parse(str)); document.write(t.getHours());
设置时间
setDate() //改变Date对象的日期 setHours() //改变小时数 setMinutes() //改变分钟数 setMonth() //改变月份,从0开始 setSeconds() //改变秒数 setTime() //改变完整的时间,毫秒数 setYear() //改变年份
日期差
求两个日期的差,就是计算两个日期之间差多少天。 1,先取得两个日期的时间戳 2,计算时间戳之间的差值 3,将时间戳之间的差值算成天 getTime() //返回完整的时间 ,毫秒数 var d1 = new Date(); var d2 = new Date("1988-6-26"); var x = d1.getTime() - d2.getTime();//毫秒 document.write(x/1000/60/60/24);
定时器
循环定时器: setInterval(函数,执行的间隔/毫秒); //连续执行 三种用法: 1. setInterval(function(){console.log(1);},1000); function fun(){ console.log(1); } 2. setInterval(fun,1000); 3. setInterval("fun()",1000); //不常用 在函数调用的时候,一般来说,"都有"(有双引号有括号),或者"都无"(无双引号无括号) 停止:clearInterval(定时器对象); //清除定时器 var i = 0; function fun(){ console.log(i++); if(i==5){ clearInterval(t); } } t = setInterval(fun,1000); -------------------------------------------- 延迟定时器: setTimeout(回调函数,毫秒数) 设置在指定的毫秒数后执行一次回调函数,返回定时器编号 体现的是延迟完成一件事情。 var t = setTimeout(function(){ document.write("hello lao wang"); },5000); clearTimeout(t); //清除定时器
动态时间
<p id="time">时间</p> var p = document.getElementById("time"); setInterval(function(){ p.innerHTML = new Date(); },1000);
BOM
Broswer Object Model 浏览器对象模型 所有属性及其方法在使用时都应该有前缀 window是所有对象的祖宗 但是window可以省略
window对象常用的属性和方法
三个弹出框:特点阻塞代码执行:所以后面的代码会被阻塞 alert("内容") 弹出框 confirm("提示信息") 确认框 确定返回true 取消返回false prompt("提示信息","默认值") 输入框 返回数值为字符串 所有全局变量都是window对象的属性 所有全局函数都是window对象的方法
两个定时器
setInterval(执行任务,间隔时间): 连续执行定时器 clearInterval setInterval(fn,时间间隔):返回的是该定时器的钥匙,clearInterval(钥匙) setTimeout(执行任务,间隔时间): 用法同上 只执行一次 延时性 clearTimeout() 停止定时器(一般用的不太多) setTimeout(fn,时间间隔):返回的是该定时器的钥匙,clearTimeout(钥匙) 延时定时器 ------------------------------- 案例:延迟关闭 <html> <head> <meta charset="utf-8" /> <title></title> <style> #box{ width: 200px; height: 200px; background-color: aqua; } </style> </head> <body> <input type="button" value="开始" id="begin"> <input type="button" value="停止" id="end"></br> <div id="box"></div> </body> </html> <script> var d = document.getElementById("box"); var b = document.getElementById("begin"); var e = document.getElementById("end"); var t = null;//注意全局变量定时器的作用域 b.onclick = function(){ t = setTimeout(function(){ d.style.display = "none"; },3000); } e.onclick = function(){ clearTimeout(t); } </script>
延迟加载onload
onload事件:onload 事件会在页面或图像加载完成后立即发生。 window.onload = function(){ console.log("页面加载完成"); } console.log("页面正在加载"); 为了解决三个弹出框的阻塞行为,可以利用延迟加载事件 延迟加载事件:当整个网页全部加载完毕后再执行该函数体 如果不添加延迟加载事件,则script必须写在页面最后,代码执行从上到下,会出现undefined window.οnlοad=function(){ var oP=document.getElementById("test"); console.log(oP.innerHTML); }
location
console.log(location); href:地址属性,可读可写 读: console.log(location.href); //读取地址
写: location.href="小游戏,4399小游戏,小游戏大全,双人小游戏大全 - www.4399.com"; //同样跳转 location.replace("小游戏,4399小游戏,小游戏大全,双人小游戏大全 - www.4399.com");//网站跳转到4399网址界面 覆盖原先网页 没有浏览痕迹
location.reload(); //页面刷新 一般不用
history
history对象包含用户(在浏览器窗口中)访问过的 URL。
方法 :(打点 )
back() 加载 history 列表中的前一个 URL。
forward() 加载 history 列表中的下一个 URL。
go() 加载 history 列表中的某个具体页面,或者要求浏览器移动到指定的页面数量(负数为后退,正数为前进)
-
-
创建节点
1.先创建 2.再连接 var oH2 = document.createElement("h2"); oH2.innerHTML = "静夜思"; //连接 document.body.appendChild(oH2); var oP1 = document.createElement("p"); oP1.innerHTML = "床前明月光,"; document.body.appendChild(oP1); 删除节点: 节点.remove(无参) 直接删除 以后这个用的更多一些 list.lastElementChild.remove();
childNodes和children
childNodes返回的是所有的孩子节点,但是实际孩子节点的长度并不是我们想要的那样,因为里面包括了文本元素
-
冒泡:由子传递父
-
捕获:由父传递子
-
1.通过HTML元素绑定事件
本质是将函数对象赋值给onclick属性
-
2.通过js对象绑定
var oBtn=document.querySelector("button"); oBtn.οnclick=function(){ console.log("erty"); } document.οnclick=function(){ alert("1"); } document.οnclick=function(){ alert("2"); } //只出现弹出2 目前事件绑定的功能缺陷: 1.无法决定事件流传递是冒泡还是捕获 2.无法为相同的元素多次绑定相同的事件 为了解决这些缺陷,出现了事件监听
-
3.事件监听
好处 1.可以为相同的元素多次绑定相同的事件 2.可以决定事件流的传递是冒泡还是捕获 使用方法: DOM对象.addEventListener(去掉on的事件名,回调函数,[事件是冒泡还是捕获]);默认不写为冒泡; (true为捕获,false和默认是冒泡) eg1:可以为相同的元素多次绑定相同的事件 document.addEventListener("click",function(){ alert("1"); }); document.addEventListener("click",function(){ alert("2"); }); //1和2都弹出 当相同的元素绑定相同的事件,且捕获和冒泡同时存在时 捕获优先于冒泡 -------------- 取消事件监听的绑定效果 方法1. document.οnclick=function(){ alert("1"); } document.οnclick=null; 方法2. var fun=function(){ alert(1); } document.addEventListener("click",fun); // 注意事项:两个方法的回调函数必须是同一个函数对象才可以取消事件绑定 document.removeEventListener("click",fun);
事件的委托
委托:让别人干你需要做的事 依赖于冒泡机制 好处1:可以通过委托机制批量为子元素添加事件,提高运行效率
注意,一般需要修改的元素,就用getElementsByTagName; oUl.οnclick=function(evt){ var e=evt||event; //核心:获取真实的操作源 var target=e.srcElement|| e.target; //获取真实操作源的标签名(都是大写); //console.log(target.tagName); if(target.tagName=="LI"){ //如果是li元素,则 target.style.backgroundColor="hotpink"; } } 等价于: oUl.addEventListener("click",function(evt){ var e=evt || event; var target=e.srcElement||e.target; if(target.tagName=="LI"){ target.style.backgroundColor="red"; } })
事件委托的好处2 可以为未来创建的元素,提前通过父元素绑定事件
var oText=document.querySelector("input"); var oBtn=document.querySelector("button"); var oUl=document.querySelector("ul"); oUl.οnmοuseοver=function(evt){ //鼠标放上 var e=evt||event; var target=e.srcElement||e.target; if(target.tagName=="LI"){ target.style.backgroundColor="pink"; } } oUl.οnmοuseοut=function(evt){ //鼠标放开 var e=evt||event; var target=e.srcElement||e.target; if(target.tagName=="LI"){ target.style.backgroundColor=""; } oBtn.οnclick=function(){ //添加新元素 var oLi=document.createElement("li"); oLi.innerHTML=oText.value; oUl.appendChild(oLi); } }
JSON对象和字符串的相互互换
json对象和字符串的相互转换 ES6提供两个函数 字符串->json对象 var str='{"name":"老王","age":18}'; var json=JSON.parse(str); console.log(json.name,json.age); json对象 ->字符串 var json={"name":"老王","age":18}; var str=JSON.stringify(json); console.log(typeof str);
正则对象的创建
正则对象的创建 1.构造方法 var reg=new RegExp("格式控制字符串",["修饰符"]);
eg: let reg = new RegExp(old, "g");
var reg=new RegExp("a"); //判断目标字符串是否存在一个a
2.字面量方法 var reg=/格式控制字符串/修饰符;
eg:
var reg=/a/; console.log(reg.test("abss"));
test
test 功能:判断,目标字符串是否满足正则格式,返回布尔值 参数:test(目标字符串) 返回值:布尔值 console.log(reg.test("abc"));
exec
功能:判断目标字符串是否满足正则对象的格式,将满足格式的子串返回至一个长度为1的数组 参数:exec(目标字符串) 返回值:满足条件的字串 g修饰符 golble全局 i修饰符:忽略大小写
正则格式控制字符
/格式字符串/修饰符 格式字符串:普通字符, 特殊字符: a.单个字符 b.组合字符 c.各种括号
至少包含一个a var reg=/a/; 至少包含5个a var reg=/aaaaa/; 只能包含一个a reg=/^a$/; // 注意事项: // 正则的判断只有至少或只能 // ^$同时出现同时消失 只能包含5个a reg=/^aaaaa$/; reg=/^a{5}$/; 以b开头,至少3个a 至多5个a reg=/^ba{3,5}$/; 6个5 reg=/^5{6}$/; 邮编 6位数字 reg=/\d{6}^$/; 定义一个由字母或数字或下划线组成的用户名,范围6,18之间 reg =/^\w{6,18}$/; 定义一个由字母或数字或下划线组成的用户名,范围6,18之间,首字母不能为数字 reg =/^\D\w{5,17}$/; 定义一个密码 至少6位 reg=/^.{6,}$/; //.代表任意元素 // www.baidu.com reg=/^www\.baidu\.com$/; 如何打印一个\ reg=/^\\$/; //\为转义字符 写一个3+5 reg=/^3\+5$/; 以13或15开头的手机号 a.表示或的方法|和()结合 // (5|3); reg=/^1(3|5|7)\d{9}$/; b.表示或的方法 // [157] reg=/^1[357]\d{9}$/; 范围取值:获取a-z之间的1个任意字符 reg=/^[a-zA-Z0-9]$/; 空格 reg=/^\s$/; 除了 reg=/^[^1a!]$/; //中文编码格式[\u4e00-\u9fa5] 两个中文 reg=/^[\u4e00-\u9fa5]{2}$/;
表单的验证
form action:提交的服务器地址 method:数据提交的方式,默认为get get:五菱宏光,效率高,安全性低,携带数据数据量小 post:武装押运,效率低,安全性高,携带数据量大 onblur取消焦点 onsubmit:提交事件
字符串相关方法
将正则作为参数
search
search 功能:返回匹配的字串的首位置下标 参数:search(正则对象) 返回值:找到返回字串下标,找不到返回-1 eg: var str="HelloWorld"; var reg=/wor/i; console.log(str.search(reg)); //5
match
match 功能:根据正则对象格式,返回匹配子串,存入数组 参数:match(正则对象); 返回值:数组 eg: var reg=/\d+/g; var str="123a456b789"; console.log(str.match(reg)); // ['123', '456', '789']
replace
replace方法 返回根据正则表达式进行文字替换后的字符串的复制 stringObj.replace(RegExp,replaceText) eg: var str = "gongjunjie de ge bi zhu zhe gongjunjie"; str=str.replace(/gongjunjie/g,"老王"); console.log(str); //老王 de ge bi zhu zhe 老王
正则特殊字符
单个字符: ^:正则开始 $ : 正则结束 . : 元字符, 表示任意一个字符 \. : 表示转义字符 \.表示. +: 表示其前面紧挨着的字符至少出现1次 等价{1,} * :表示其前面出现的字符至少出现过0次 等价{0,} ?: 表示其前面出现的字符至少出现过0次,至多1次 等价{0,1} | : 表示或者 组合字符: \d : 0-9之间的任意一个数字 \d只占一个位置 \D : 除了\d \w : 数字,字母 ,下划线 0-9 a-z A-Z _ \W : 除了\w \s : 空格或者空白等 \S : 除了\s 括号: {m,n}表示括号前面紧挨着的字符至少出现m个,至多出现n个 : 以b开头 至少3个a 至多5个a /^ba{3,5}&/ {m}表示括号前面紧挨着的字符只能出现m个 {m,}表示括号前面紧挨着的字符至少出现m个 [] 表示括号内的任意一个字符 [wd3h] [a-z]表示任意一个小写字母 [a-zA-Z0-9] [^ ]表示非括号内的任意一个字符 ()一般与或连用 表示优先级 [\u4e00-\u9fa5] 任意一个中文字符
let(ES6新增)
let本质和var是一样的,都是用来声明变量的
1.块级作用域:在该块的范围内,才能使用该变量,且该变量不会消失
2.暂时性死区(作用域不同的情况下,当内部变量与外部变量同名时,内部变量屏蔽外部变量) 3.变量必须先定义后使用
4.变量不能重复定义
只读变量
只读变量 const 修饰的变量为只读变量
a.变量只能读不能改
b.被const修饰的变量必须被初始化
c.必须先定义后使用
d.不能重复定义
e.块级作用域
不成文的规定,只读变量通常全部为大写
const PI=3.1415926535;
-
C/S架构:client/Server
(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销, 可以充分利用两端硬件环境的优势。 开发C/S架构可以采用多种语言,包括Java,C++,C#,以及Dephi等
-
B/S架构: Browser/Server
```+js 即Browser/Server(浏览器/服务器)结构,是随着技术Internet的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下, 用户界面完全通过WWW浏览器实现。前端在大部分企业就是做浏览器端展现相关的工作,会用到html,css,js,ps,ai等等,而“后端”的主要工作室程序开发、数据处理了,比如:php,asp,mysql,mssql。 ```
-
关系型数据库:Oracle、MySQL、SQLServer、DB2、sybase
(关系型数据库:之间有联系)
-
非关系型的数据库:Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite, HBase,CouchDB,Hypertable, Riak,Ti,
-
1.创建数据库:
可视化:点击鼠标右键 代码: create database 数据库名 如: create database db20170203
-
2.创建表:
-
3.sql语句:增,删,查,改
--增--------------------------------------- insert into 表名[字段1,字段2...字段N] values(值1,值2,值N); eg: insert into student(name, sex, age) values("孙丽华", "女", 21); insert into Student values(1,"大黄",666,18); insert into Student values(3,"小明",666,18); insert into Student(stuId,stuName) values(2,"laowang"); --删 直接删除整个表的内容,但是表还在---------------- delete from 表名 where 条件; eg: * delete from students; 删除表中的所有数据, * delete from students where id=2; //删除表中,id是2的数据。 * delete from students where age<20; -------------------------------------------- delete from Student; --整个表都删掉 drop table Student; --where 条件 类似于if delete from Student where stuName = "大黄" -------------------------------------- --OR类似于 || delete from Student where stuId = 1 OR stuName = "小明"; -------------------------------------- --AND类似于&& delete from Student Where stuName = "大黄" AND stuid = 1; ============================================= --改 update 表明 set 字段1=值1,字段2=值2... WHERE 更新条件; update student set stuName = "啦啦啦",stuId = 12323 where stuname = "嘿嘿"; =============================================== --查 select 列名称 from 表名称 [查询条件]; * select name, age from students; * select * from students; * select * from students where age > 21 ; * select * from students where name like "%王%"; --模糊查询 * select * from students where id<5 and age>20; 如: select stuAge,stuId,stuAge from Student; select*from Student;
PHP连接MySql
mysql_connect(servername,username,password);
参数描述
servername可选。规定要连接的服务器。默认是 "localhost:3306"。
username可选。规定登录所使用的用户名。默认值是拥有服务器进程的用户的名称。
password可选。规定登录所用的密码。默认是 ""。
-
1.创建数据库连接对象
$conn = mysql_connect("localhost","root","root");
-
2.选择数据库
mysql_select_db("xa1901");
-
3.数据库操作
数据库查询 mysql_query(sql语句,连接对象); ----------------------------- 增: mysql_query("insert into student values(999,'大王','M','23')",$conn); 删: mysql_query("delete from student where stuName = '小明'",$conn); 改: mysql_query("update student set stuname='蝙蝠侠' where stuid = 999",$conn); ============ 查 返回结果集,类似于一张表 mysql_num_rows(结果集):返回当前结果集对应的记录数 $result=mysql_query("select * from student",$conn); $row=mysql_num_rows($result); 一般我们需要的是表格的东西,而不是表格记录的个数,所以一般用作判断 登录注册的条件,返回1,则说明数据存在,只需要登录 通常作为登录注册的判断条件 $result=mysql_query("select * from student where stuName='哈哈'",$conn); if(mysql_num_rows($result)==1){ echo "登录成功"; }else{ echo "登录失败"; } // 获取数据库中的某条记录 // mysql_fetch_assoc("结果集"):返回当前游标所指向的记录,以对象的方式存储 // 注意事项:mysql_fetch_assoc方法每执行完一次,游标会自动下移 $result=mysql_query("select * from student",$conn); while($obj=mysql_fetch_assoc($result)){ echo $obj["stuId"]."". $obj["stuName"]."".$obj["stuGender"]."". $obj["stuAge"].""."<br>"; }
-
4.关闭数据库
mysql_close($conn);
eg: <?php header("Content-type:text/html;charset=utf-8"); //$conn = mysql_connect("localhost","root","root"); //创建数据库连接对象 $conn = mysql_connect("localhost","root","root"); if($conn){ echo "连接成功"."</br>"; //选择数据库 mysql_select_db("xa1901"); }else{ die("Could not connect:" . mysql_error()); } //数据库查询 //mysql_query(sql语句,连接对象); //增 // mysql_query("insert into student values(999,'大王','M','23')",$conn); //删 //mysql_query("delete from student where stuName = '小明'",$conn); //改 //mysql_query("update student set stuname='蝙蝠侠' where stuid = 999",$conn); //返回的是一个表格 $result = mysql_query("select * from student where stuid = 2",$conn); //返回结果集中的字段数,也就是列数 $result_col = mysql_num_fields($result); //返回行数 $result_row = mysql_num_rows($result); echo $result_row; if($result_row == 1){ echo "存在"; }else{ echo "不存在"; //判断结果集的行数 if(mysql_num_rows($result)>0){ //将结果集放到数组$rows while($rows = mysql_fetch_assoc($result)){ echo $rows["stuName"]." ".$rows["stuAge"]; } } } mysql_close($conn); ?>
*注意事项:
1.php的变量名在字符串中,依然代表变量的内容
2.字符串嵌套字符串必须转义
cookie
cookie的存
存: document.cookie="key=value"; eg: document.cookie="name=laowang"; 多个cookie都要分开定义 document.cookie="age=18"; 没有key的时候为增,有key的时候为改 document.cookie="name=huanghh"; 取:每两组键值对之间用户分号和空格隔开 // age=18; name=huanghh console.log(document.cookie); --------------------------------- cookie的生命周期 会话级别: document.cookie="key=value"; eg: document.cookie="name=caoboyong"; 长生命周期: document.cookie="key=value;expires="+标准日期对象; eg: let date=new Date(); date.setDate(date.getDate()+10); document.cookie="name=laowang;expires="+date; cookie没有直接删除 // cookie只能侧面删除 // a.将key对应的value设置成字符串 // b.将expires设置为-1 document.cookie="key='';expires=-1";
同步与异步
同步:代码按照顺序一步一步执行,遇到需要消耗等待时间的代码块,会阻塞代码执行
异步:遇到需要消耗时间的代码块,非阻塞程序执行,先去执行后续代码
异步代码:和消耗等待时间有关
a.定时器
b.事件体
document.οnclick=function(){ console.log("gghhh"); //异步代码 }
c.发送请求和接收响应
同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的, 只有接收到返回的值或消息后才往下执行其他的命令。 异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程, 那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。
注意:当同步代码和异步代码同时存在时,同步代码优先执行,与书写顺序无关
eg: console.log(1); setTimeout(function(){ console.log(2); //异步代码后执行 },0); setTimeout(function(){ console.log(3); },0); setTimeout(function(){ console.log(4); },0); console.log(5); // 1 5 2 3 4 console.log(1); setTimeout(function(){ console.log(2); //异步代码后执行 },100); setTimeout(function(){ console.log(3); },200); setTimeout(function(){ console.log(4); },20); console.log(5); //1 5 4 2 3 let time=setTimeout(function(){ //同步代码 console.log(1); //异步代码 },200); clearTimeout(time); //同步代码 // 异步代码直接没有执行
ajax
1.概念
是指一种创建异步交互式网页应用的网页开发技术。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
前端通过与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
不用加载整个网页面,能够局部更新网页的技术
-
为什么要使用AJAX
* 更自然、流畅的用户体验,对用户的操作即时响应
* 在不中断用户操作的情况下与Web服务器进行通信
* 更灵敏的响应用户访问,实现近似于桌面应用程序的交互效果
* 通过局部更新页面降低网络流量,提高网络的使用效率
ajax步骤
1.创建XMLHttpRequest对象
let xhr=new XMLHttpRequest();
2.调用open方法
xhr.open("请求的方式get/post","请求的地址",true);
3.调用send方法
xhr.send();
4.onreadystatechange事件
xhr.onreadystatechange=function()
5.返回值---->xhr.responseText fun(xhr.responseText);
ajax的编写步骤-->打电话 // 1.掏手机--->创建XMLHttpRequest对象 let xhr=new XMLHttpRequest(); // 2.拨号--->调用open方法 // xhr.open("请求的方式get/post","请求的地址",true); xhr.open("get","4.ajaxStep.txt",true); // 3.发射-->调用send方法 xhr.send(); // 4.等待接通--->onreadystatechanges事件 xhr.onreadystatechange=function(){ // xhr.status==200等价于电话接通,(客户端请求成功) // xhr.readyState==4等价于接电话了 if(xhr.status==200 && xhr.readyState==4){ // 5.返回值---->xhr.responseText fun(xhr.responseText); } } console.log(xhr.responseText); function fun(resText){ let oSpan=document.querySelector("span"); oSpan.innerHTML=resText;
注意:get的传参方式:url?key1=value1&key2=value2...
<?php header("Content-type:text/html;charset=utf-8"); $name=$_GET["userName"]; $conn=mysql_connect("localhost","root","root"); // echo在参与ajax的PHP文件中,echo是返回responseText的关键字 mysql_select_db("db2021"); $result=mysql_query("select * from student where stuName='$name'",$conn); if(mysql_num_rows($result)==1){ echo "用户名已存在"; }else{ echo "可以注册"; } mysql_close($conn); ?>
注意: echo在参与ajax的PHP文件中,echo是返回responseText的关键字
ajax里xhr的相关属性
xhr对象的属性
-
数据的发送
get:send(无参) post:send(key1=value1&key2value2...)
xhr.send([参数]);
请求方式为get时,xhr.send()方法无参;
请求方式为post时,xhr.send(key1=value1&key2value2...)有参
post传参: 1.open方法后设置请求头,将参数以form表单的方式发送 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 2.将真正的请求参数传入send // key1=value1&key2=value2...
-
onreadystatechange:
readyState的状态码发生改变,触发该事件只有2,3,4的状态码会发生改变
-
readyState:xhr对象的状态码
0:new了一个对象 1:调用完open方法 2:调用send方法,数据发送了出去 3:数据发送到了服务器 4:服务器解析完成,返回响应 所以readystate==4才能接收响应
-
responseText:返回的响应内容
-
status:代表http协议是否流畅
xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200) { console.log(xhr.readyState); } }
ajax返回Json对象
json_encode将数组转换为JSON字符串
<script> let xhr=new XMLHttpRequest(); xhr.open("get","3.ajaxReturnJson.php",true); xhr.send(); xhr.onreadystatechange=function(){ if(xhr.status==200 && xhr.readyState==4){ fun(xhr.responseText); } } function fun(resText){ //字符串转为JSON对象 let json=JSON.parse(resText); for(let index in json){ console.log(json[index]); } } </script>
<?php header("Content-type:text/html;charset=utf-8"); // 方法一:直接通过JSON字符串返回 // echo'{"name":"laowang","age":18}'; // 方法二:通过PHP的数组返回 $arr=["name"=>"laowang","age"=>6]; // json_encode将数组转换为JSON字符串 echo json_encode($arr); //laowang //18 ?>
ajax的封装
功能:发送请求,接收响应 参数: type:get/post支持大小写 url:服务器地址 isAsyn:是否异步 data:请求参数 callBack:接收响应的回调函数
function ajaxFun(type,url,isAsyn,data,callBack){ let xhr=new XMLHttpRequest(); type=type.toLowerCase(); //转为小写 if(type=="get"){ let urlParams=url; if(data!=""){ urlParams+="?"+data; //字符串拼接 //get传参方式 } xhr.open(type,urlParams,isAsyn); xhr.send(); }else if(type=="post"){ xhr.open(type,url,isAsyn); xhr.setRequestHeader("Content-type","application/x-www/form-urlencoded"); xhr.send(data); //post传,send方法有参数,加申请头 }else{ console.log("类型错误"); } // 4.状态码事件 xhr.onreadystatechange=function(){ if(xhr.readyState==4 && xhr.status==200){ callBack(xhr.responseText); } } }
promise
-
promise作用:将函数嵌套调用的方式,改为平级调用,避免回调地狱问题。
换而言之,功能未发生改变,换种语法传递回调函数。
-
promise语法:
1.promise是一个对象
2.promise通常放在一个函数体内
3.将promise对象作为函数的返回值返回
then是promise对象的一个方法
通过then方法把原来的回调函数传进去
Promise对象.then(callBack1,[callBack2]);
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html> <script> // 回调地狱 // function f1(f){ // console.log("f1"); // f(); //f==f2 f()==f2 // } // function f2(f){ // console.log("f2"); // f(); // } // function f3(f){ // console.log("f3"); // f(); // } // function f4(){ // console.log("f4"); // } //嵌套调用 //注意事项:今天千万不要研究这个 // f1(function() { // f2(function() { // f3(f4); // }); // }); //------------------------------------------------ // promise作用:将函数嵌套调用的方式,改为平级调用,避免回调地狱问题。 // 换而言之,功能未发生改变,换种语法传递回调函数。 // promise语法: // 1.promise是一个对象 // 2.promise通常放在一个函数体内 // 3.将promise对象作为函数的返回值返回 function f1() { console.log("f1"); let p = new Promise(function(callBack1) { callBack1(); }); return p; } function f2() { console.log("f2"); let p = new Promise(function(callBack1) { callBack1(); }); return p; } function f3() { console.log("f3"); let p = new Promise(function(callBack1) { callBack1(); }); return p; } function f4() { console.log("f4"); } // then是promise对象的一个方法 // 通过then方法把原来的回调函数传进去 // Promise对象.then(callBack1,[callBack2]); f1().then(f2).then(f3).then(f4); //f1(f2); </script>
跨域访问
ajax不能进行跨域,因为浏览的安全机制;
JSONP是一种跨域访问技术,跨域访问时,被访问的文件必须放到www根目录下.
跨域访问原理:同源策略:同IP,同协议,同端口.
本质是利用html的src支持跨域
jsonp跨域技术
-
-
jsonp是一种跨域技巧,本质是利用HTML标签src可以跨域的机制实现
-
跨域访问的步骤
-
1.前端定义函数
2.后端调用函数,通过实参传递数据给前端
3.前端通过script的src导入后端文件,模拟数据响应目录
-
跨域全局资源共享
后端加: header("Access-Control-Allow-Origin:*");
-
<?php // 跨域全局资源共享 // header("Access-Control-Allow-Origin:*"); header("Content-type:text/html;charset=utf-8"); $cb=$_GET["cb"]; echo "$cb('上海自来水来自海上')"; ?>
接口
-
接口:前端发送请求,后端返回响应的文件地址(包含3部分)
-
url:服务器请求的文件地址
-
参数:请求参数
-
响应内容:返回的数据格式
-
url:http://suggestion.baidu.com/su
参数:wd 关键字
cb:约定的函数名
返回值:{
q:关键字,
p:没用,
s:[数据1,数据2,]
}
jsonp搜索引擎 各大搜索引擎智能提示API 利用接口获取后端的数据