编程语言
编程:就是让计算机为解决某个问题而使用某个程序设计语言编写程序代码,并最终得到结果的过程。
计算机程序:就是计算机所执行的一系列的指令集合,而程序全部都是用我们所掌握的语言来编写的,所以人们要控制计算机一定要通过计算机语言向计算机发出指令。
注意:上面所定义的计算机指的是任何能执行代码的设备,可能是智能手机、ATM机、黑莓pl、服务器等等
计算机语言
计算机语言指用于人与计算机之间通讯的语言,他是人与计算机之间传递信息的媒介。
计算机语言的种类非常多,总的来说可以分成机器语言,汇编语言和高级语言三大类
实际上计算机最终执行的都是机器语言,它是由“0”和“1”组成的二级制数,二进制计算机语言的基础。
编程语言
可以通过类似于人类语言的“语言”来控制计算机,让计算机为我们做事情,这样的语言叫做编程语言(programming Language)。
编程语言是用来控制计算机的一系列指令,它有固定的格式和词汇(不同编程语言的格式和词汇不一样),必须遵守。
汇编语言和机器语言实质是相同的,都是直接对硬件操作,只不过是采用了英文缩写的标识符,容易识别的记忆。
高级语言主要相对于低级语言而言,他并不是特质某一种具体的语言,而是包括了很多编程语言,常用的有C语言、C++、java、C#、python、PHP、javascript、go语言、objective-C、swift等。
翻译器
高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行,为此,我们需要一个翻译器。
翻译器可以将我们所编写的源代码转换为机器语言,这也被称为二进制化。记住1和0.

编程语言和标记语言区别
编程语言有很强逻辑和行为能力。在编程语言里。你会看到很多if else、for、while等具有逻辑和行为能力的指令,这是主动的。
标记语言(html)不用于向计算机发出指令,常用于格式化和链接。标记语言的存在是用来被读取的,他是被动的。
javascript是什么
JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言(script是脚本的意思)
脚本语言:不需要编译,运行过程由js解释器(js引擎)逐行来进行解释并执行
现在也可以基于node.js技术进行服务器端编程
javascript的作用
表单动态校验
网页特效
服务端开发(Node.js)
桌面程序(Electron)
App(cordova)
控制硬件-物联网(Ruff)
游戏开发(cocos2d-js)
浏览器执行JS简介
浏览器分成两部分 渲染引擎和js引擎
渲染引擎:用来解析html和css,俗称内核,比如chrome浏览器blink,老版本的webkit。
js引擎:也成为js解释器,用来读取网页中的JavaScript代码,对其处理后运行,比如chrome浏览器的v8
浏览器本身并不会执行JS代码,而是通过内置JavaScript 引擎(解释器) 来执行J5代码。JS引擎执行代码时逐行解释
每—句源码(转换为机器语言),然后由计算机去执行,所以JaveScript 语言归为的脚本语言,会逐行解释执行.
JS的组成

1.ECMAScript
ECMAScript是由ECMA国际(原欧洲计算机制造协商会)进行标准化的一门语言,这种语言在万维网上应用广泛,他往往被称为JavaScript或JScript,但实际上后两者都是ECMAScript语言的实现和扩展。

ECMAScript:ECMAScript规定了JS编程语言和核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。
2.DOM——文档对象模型
文档对象模型 是W3C组织推荐的处理可扩展标记语言的标准编程接口。
通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等}
JS初体验
JS有三种书写位置,分别为行内、内嵌和外部。
1.行内式JS
input type=“button” value=“点我试试” οnclick=“alert('Hello world”)" />
可以将单行或少量JS代码写在html标签的事件属性中(以on开头的属性),如:onclick
注意单引号的使用:在html中我们推荐使用双引导,JS中我们推荐使用单引导
可读性差,在html中编写大量JS代码时,不方便阅读;
引号易错,引导多层嵌套匹配时,非常容易弄混;
特殊情况下使用
2.内嵌JS
可以将多行JS代码写到
3.外部JS文件
利用html页面代码结构化,把大段JS代码独立到html页面之外,既美观,也方便文件级别的复用
引入外部JS文件的script标签中间不可以写代码
适合于JS代码量比较大的情况
什么是变量?
白话:变量就是装东西的盒子。
通俗:变量是用于存放数据的容器。我们通过变量名获取数据,甚至数据可以修改。
变量的使用
变量在使用时分为两步:1.声明变量 2.赋值
1.声明变量
//声明变量
var age;//声明一个名称的变量
var 是一个JS关键字,用来声明变量(variable变量的意思)。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管
age是程序员定义的变量名,我们需要通过变量名来访问内存中分配的空间
2.赋值
age=10;//给age这个变量赋值为10
=用来把右边的值赋给左边的变量空间中 此处代表赋值的意思
变量值是程序员保存到变量空间里的值
变量的初始化
var age =18; //声明变量同时赋值为18
声明一个变量并赋值,我们称之为变量的初始化。
//1.声明一个age的变量
var age;
//2.赋值 把值存入这个变量中
age = 18;
//3.输出结果
console.log(age);
//4.变量的初始化
var myname ='pink老师';
console.log(myname);
变量语法扩展
1.更新变量
一个变量重新赋值后,他原有的值就会被覆盖,变量值将以最后一次赋值为准。
var age = 18;
age = 81; //最后的结果就是81因为18被覆盖了
2.同时声明多个变量
同时声明多个变量,只需要写一个var,多个变量名之间用英文逗号隔开
var age = 10, name=‘zs’, sex=2;

3.声明变量的特殊情况
情况 | 说明 | 结果
var age;console.log(age); | 只声明不赋值 | undefined(未定义)
console.log(age) | 不声明 不赋值 直接使用 | 报错
age = 10;console.log(age) | 不声明只赋值 | 10
变量命名规范
由宁字母(4-2a-2人数字(0-9)、下划结()、美元符号($)組成,如:usrAge, num01, name
严格区分大小写。varapp;和 var App;是两个变量
不能以数字开头 。18age 是错误的
不能 是关键宇、保留字。例如:var. for、 while
变量名必须有意义。MMD BBD nl——age
遵守驼峰命名法。首字母小亏,后面单词的首字母需要大写。myFirstName
推荐翻译网站:有道 爱词霸
为什么需要数据类型
在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型。
简单来说,数据类型就是数据的类别型号。比如姓名“张三”,年龄18,这些数据的类型是不一样的。
变量的数据类型
变量是用来存储值的所在处,它们的名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。javascript是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会自动确定。
var age = 10; //这是一个数字型
var areYouOk=‘是的’ //这是一个字符串
在代码运行时,变量的数据类型是由JS引擎根据=右边的变量值的类型来判断的,运行完毕之后,变量就确定了数据类型。
JavaScript拥有动态类型,同时也意味着相同的变量可用作不同的类型:
var x = 6; //x为数字型
var x =“bill” //x为字符串型
数据类型的分类
JS把数据类型分为两类:
简单数据类型(Number,String,Boolean,Undefined,Null)
复杂数据类型(object)
2.1简单数据类型(基本数据类型)
JavaScript中简单的数据类型如下:
简单的数据类型 | 说明 | 默认值
Number | 数字型,包含 整型值和浮点型值,如21、0.21 | 0
Boolean | 布尔值型,如true、false,等价于1和0 | false
String | 字符串类型,如“张三”注意咱们JS里面,字符串都带引号 | “”
Undefined | var a;声明了变量a但没有给值,此时a=undefined | undefined
Null | var a =null;声明了变量a为空值 | null
2.2数字型Number
JavaScript数字类型既可以用来保存整数值,也可以保存小数(浮点数)。
var age = 21; //整数
var Age = 21.3747 //小数
1.数字型进制
最常见的进制有二进制、八进制、十进制、十六进制。
//1.八进制数字序列范围:0-7
var num1 = 07; //对应十进制的7
var num2 = 019; //对应的十进制19
var num3 = 08; //对应的十进制的a
//2.十六进制数字顺序范围:0-9以及A-F
var num = 0xA;
现阶段我们只需要记住,在JS中八进制前面加0,十六进制前面加0x
2.数字型范围
JavaScript中数值的最大数和最小值
alert(Number .MAX_VALUE); //1.7967931348623157e+308
alert (Number .MIN_VALUE); //5e-324
3.数字型三个特殊值
alert (Infinity); //Infinity
alert (-Infinity); //-infinity
alert (NaN); //NaN
lnfinity,代表无穷大,大于任何数据
-lnfinity,代表无穷大,小于任何数值
NaN,Not a number,代表一个非数值
4.isNaN()
用来判断一个变量是否为非数字的类型,返回true或者false


字符串型 String
1.字符串引号嵌套
字符串型可以是引号的任意文本,其语法为双引号“”和单引号‘’

JS可以用单引号嵌套双引号,或者用双引号嵌套单引号(外双内单,外单内双)
2.字符串转义符
类似html里面的特殊字符,字符串也有特殊字符,我们称之为转义符。
转义符都是\开头的,通常的转义符及其说明如下:
转义符 | 解释说明
\n | 换行符,n是newline的意思
\ | 斜杠
’ | ‘单引号
* | “双引号
\t | tab缩进
\b | 空格,b是blank的意思
3.字符串长度
字符串是由若干个字符组成的,这些字符的数量就是字符串的长度。通过字符串的lenght属性可以获取整个字符串的长度
var strMsg = “我是帅气多金的程序猿!”;
alert (strMsg.length); //显示11
4.字符串拼接
多个字符串之间可以使用+进行拼接,其拼接方式为字符串+任何类型=拼接之后的新字符串
拼接前会把字符串相加的任何类型转成字符串,再拼接成一个新的字符串


+号总结口诀:数值相加,字符相连
5.字符串拼接加强


2.5布尔型 Boolean
布尔类型有两个值:true(1)和false(0),其中true表示真(对),而false表示假(错)。
2.6Undefined 和 Null
一个声明后没有赋值的变量会有一个默认值undefined(如果进行相连或者相加时,注意结果)

3.获取变量数据类型
3.1获取检测变量的数据类型
typeof 可用来获取检测变量的数据类型。
3.2字面量
字面量是源代码中一个固定值的表示法,通俗来说,就是字面量表示如何表达这个值。
数字字面量:8,9,10
字符串字面量:‘黑马程序员’,“大前端”
布尔字面量:true,false
4.数据类型转换
4.1什么是数据类型转换
使用表单、prompt获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算,而需要转换变量的数据类型。通俗来说,就是把一种数据类型的变量转换成另外一种数据类型。
转换为字符串类型
转换成数字型
转换成布尔型
4.2转换成字符串
方式 | 说明 | 案例
toString() | 转成字符串 | var num=1;alert(num.toString())
String()强制转换 | 转成字符串 | var num=1;alert(String(num));
加号拼接字符串 | 和字符串拼接的结果都是字符串 | var num=1;alert(num+“我是字符串”)
toString()和String()使用方式不一样。
三种拼接方式,我们更喜欢第三种加号拼接字符转换方式,这一种方式也称之为隐式转换。
//1.数字型转换成字符串型 变量.toString()
var num = 10;
var str = num.toString();
console.log(str);
console.log(typeof str);
//2.我们利用 String(变量)
console.log(String(num));
//3.利用+拼接字符串的方法实现转换效果 隐式转换
console.log(num+’’);
4.3转换为数字型(重点)
方式 | 说明 | 案例
parselnt(string)函数 | 将string类型转换成整数数值型 | parselnt(‘78’)
parseFloat(string)函数 | 将string类型转成浮点数数值型 | parseFloat(‘78.21’)
Number()强制转换函数 | 将string类型转换成数值型 | Number(‘12’)
js隐式转换(-* /) | 利用算术隐式转换成数值型 | ‘12’-0
注意parseInt和parseFloat单词的大小写,这2个是重点
隐式转换是我们在进行运算的时候。JS自动转换了数据类型
4.4转换为布尔型
方式 | 说明 | 案例
Boolean()函数 | 其他类型转换成布尔型 | Boolean(‘true’)
代表空、否定的值会被转换为false,如”、0、NaN、null、undefined
其余值都会被转换成true
console.log(Boolean(’’)); //false
console.log(Boolean(0)); //false
console.log(Boolean(NaN)); //false
console.log(Boolean(null)); //false
console.log(Boolean(undefined)); //false
console.log(Boolean(‘你好吗’));
console.log(Boolean(‘我很好’));
console.log(Boolean(‘123’));
1.解释型语言和编译型语言
1.概述
计算机不能直接理解任何除机器语言以外的语言,所以必须要把程序员所写的程序语言翻译成机器语言才能执行程序。程序语言翻译成机器语言的工具,被称为翻译器。

翻译器翻译的方式有两种:一个是编译,另外一个是解释。两种之间的区别在于翻译的时间点不同
编译器是在执行代码之前进行编译,生成中间代码文件
解释器是在运行时进行及时解释,并立即执行(当编译器以解释方式运行的时候,也称之为解释器)

2.标识符、关键字、保留字
1.标识符
标识(zhi)符:就是指开发人员为变量、属性、函数、参数取的名字。
标识符不能是关键字或保留字。
2.关键字
关键字:是指JS本身已经使用了的字,不能再用他们充当变量名、方法名。
包括:break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with等。
3.保留字
保留字:实际上就是预留的“关键字”,意思是现在虽然还不是关键字,但是未来可能会成为关键字,同意不能使用他们当变量名或方法名。
包括:boolean. byte, chars,class, const, debugger, double, enum, export, extends,fimal.float, goto, implements, import, int, interface,long, mative, package,private, protected,public.short.static,super,synchronized,throws,transient
volatile等。
运算符(operator)也被称为操作符,是用于实现赋值,比较和执行算术运算等功能的符号。
JavaScript中常用的运算符有:
算数运算符
递增和递减运算符
比较运算符
逻辑运算符
赋值运算符
算术运算符概述
概念:算术运算使用的符号,用于执行两个变量或值的算术运算。
运算符 | 描述 | 实例
所以:不要直接判断两个浮点数是否相等!
1.我们怎么判断一个数能够被整除呢?
它的余数是0就说明这个数能被整除,这就是% 取余运算符的主要用途
2.请问1+2*3结果是?
结果是7,注意算数运算符的优先级,先乘除后加减,有小括号先算小括号里面的
表达式和返回值
表达式:是由数字、运算符、变量等以能求得数值的有意义排列方法所得的组合
简单理解:是由数字、运算符、变量等组成的式子
表达式最终都会有一个结果,返回给我们,我们称为返回值。
递增和递减运算符
如果需要反复给数字添加或减去1,可以使用递增(++)和递减(–)运算符来完成。
在JavaScript中,递增(++)和递减(–)既可以放在变量前面,也可以放在变量的后面。放在变量的前面时,我们可以称为前置递增(递减)运算符,放在变量后面时,我们可以称之为后置递增(递减)运算符。
3.2递增运算符
1.前置递增运算符
++num前置递增,就是自加1,类似于num=num+1,但是++num写起来更简单。
2.后置递增运算符
num ++后置递增,就是自加1,类似于num=num+1,但是num++写起来更简单
口诀 先返回值 后自加1
//前置自增
//1.想要一个变量自己加1 num=num+1 比较麻烦
var num=1;
num = num + 1; //++num
num = num + 1;
console.log(num); //3
//2.前置递增运算符 ++写在变量前面
var age = 10;
++age //类似于age = age + 1
console.log(age);
//3. 先加1 后返回值
var p = 10;
console.log(++p + 10);
//后置自增
var num= 10;
num++; //num = num + 1
console.log(num);
//1.前置自增和后置自增如果单独使用 效果是一样的
//2.后置自增 口诀:先返回值 后自加1
var age = 10;
console.log(age++ + 10); //age++ 先返回原值10 10+10+20 然后age加1
console.log(age);
3.3前置递增和后置递增小结
前置递增和后置递增运算符可以简化缩写,让变量的值+1 比以前写法更简单
但是使用时,运行结果相同
与其他代码联用时,执行结果会不同
后置:先原值运算,后自加(先人后己)
前置:先自加,后运算(先及后人)
开发时,大多是使用后置递增/减,并且代码独占一行,例如:num++;或者num–;
比较运算符
4.1比较运算符概述
概念:比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(true/false)
作为比较运算的结果。
运算符名称 | 说明 | 案例 | 结果
< | 小于号 | 1<2 | true
| 大于号 | 1>2 | false
= | 大于等于号(大于或者等于) | 2>=2 | true
<= | 小于等于号(小于或者等于) | 3<=2 | false
== | 判等号(会转型) | 3737 | true
!= | 不等号 | 37!=37 | false
=== ! | 全等 要求值和 数据类型都一致 | 37===‘37’ | false
1.我们程序里面的等于符号 是== 默认转换数据类型 会把字符串型的数据转换为数字型 只要求值相等就可以
2.我们程序里面会有全等 一模一样 要求 两侧的值 还有 数据类型完全一致才可以 true
4.2 =小结
符号 | 作用 | 用法
= | 赋值 | 把右边给左边
== | 判断 | 判断两边值值是否相等(注意此时有隐式转换)
=== | 全等 | 判断两边的值和数据类型是否完全相同
console.log(18==‘18’); //true
console.log(18===‘18’) //false
逻辑运算符
5.1逻辑运算符概述
概念:逻辑运算符是用来进行布尔值运算的运算符,其返回也是布尔值。后面开发中常用于多个条件判断。
逻辑运算符 | 说明 | 案例
&& | “逻辑与”,简称“与”and | true&&false
| | | “逻辑或”,简称“或”or | true | | false
! | “逻辑非”,简称“非”not | !true
5.2 逻辑与&&
两侧都是true才返回ture,否则返回false

5.3 逻辑或||
两边都为false才返回false,否则都为true

5.4 逻辑非 !
逻辑非(!)也叫做去反符,用来取一个布尔值相反的值
5.4短路运算(逻辑中断)
短路运算的原理:当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值。
1.逻辑与
语法:表达式1&&表达式2
如果第一个表达式为真,则返回表达式为2
如果第一个表达式的值为假,则返回表达式1
2.逻辑或
语法:表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1
如果第一个表达式为假,则返回表达式2
//1.用我们的布尔值参与的逻辑运算 true && false == false
//2.123 && 456 是值 或者是 表达式 参与逻辑运算?
//3.逻辑与短路运算 如果表达式1为真 则返回表达式2
console.log(123 && 456); //456
console.log(0 && 456); //0
console.log(0 && 1+2 && 456 * 56789); //0
// 如果有空的或者否定的为假 其余都是真的 0 '' null undefined NaN
//4.逻辑或短路运算 如果表达式1 结果为真 则返回的是表达式1 如果表达式1 结果为假 其返回的表达式2
console.log(123 || 456); //123
console.log(123 || 456 || + 123); //123
console.log(0 || 456 || + 123); //456
// 逻辑中断很重要 它会影响我们程序结果
var num = 0;
console.log(123||num++);
console.log(num); //0
赋值运算符
概念:用来把数据赋值给变量的运算符。
赋值运算符 | 说明 | 案例
= | 直接赋值 | var usrName=‘我是值’;
+=、-= | 加、减一个 数 后在赋值 | var age = 10;age+=5; //15
=、/=、%= | 乘、除、取模 后在赋值 | var age = 2;age=5;//10
var num = 10;
// num = num + 1; num++
// mun = num + 2; //num+=2;
// num += 2;
num += 5; //相当于age = age + 5;
console.log(num);
var age = 2;
age *= 3;
console.log(age);
运算符的优先级
优先级 | 运算符 | 顺序
1 | 小括号 | ()
2 | 一元运算符 | ++ – !
3 | 算数运算符 | 先* / 后±
4 | 关系运算符 | > >= < <=
5 | 相等运算符 | == != === !==
6 | 逻辑运算符 | 先&& 后 ||
7 | 赋值运算符 | =
8 | 逗号运算符 | ,
一元运算符里面的逻辑非优先级很高
逻辑与比逻辑或优先级高
1.流程控制
在一个程序执行的过程中,各条代码的执行顺序对程序的结果是有直接影响的。很多时候我们要通过控制代码的执行顺序来实现我们要完成的功能。
简单理解:流程控制就是来控制我们的代码按照什么结构顺序来执行
流程控制主要有三种结构,分别是顺序结构、分支结构和循环结构,这三种结构代表三种代码执行的顺序。

顺序结构控制
顺序结构是程序中最简单、最基本的流程控制,他没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

3.分支流程控制if语句
3.1分支结构
由上到下执行代码过程中,根据不同的路径代码(执行代码多选一的过程),从而得到不同的结果

JS语言提供了两种分支结构语句
if语句
switch语句
3.2 if语句
1.语法结构
//条件成立执行代码,否则什么也不做
if (条件表达式){
//条件成立执行的代码语句
}
语句可以理解为一种行为,循环语句和分支语句就是典型的语句。一个程序由很多个语句组成,一般情况下,会分割成一个一个的语句。
2.执行流程

//1.if 语法结构 如果if
// if (条件表达式) {
// //执行语句
// }
//2.执行思路 如果if里面的条件表达式结果为真 true 则执行大括号里面的 执行语句
//如果if 条件表达式结果为假 则不执行大括号里面的语句 则执行if 语句后面的代码
//3.代码体验
if(3 < 5) {
alert(‘我最帅’)
}
进入网吧案例
//弹出 prompt 输入框,用户输入年龄,程序把这个值取过来保存变量中
//使用if语句来判断年龄,如果怕年龄大于18 就执行if 大括号里面的输出语句
var age = prompt(‘请输入年龄’)
if (age >= 18) {
alert(‘我想带你去网吧偷耳机’)
}
3.3 if else语句(双分支语句)
//条件成立执行代码,否则什么也不做
if (条件表达式){
//条件成立执行的代码语句
} else {
//[否则执行的代码
}
2.执行流程

//1.语法结构 if 如果 else否则
// if (条件表达式) {
// //执行语句
// } else {
// //执行语句2
// }
//2.执行思路 如果表达式结果为真 那么执行语句1 否则 执行语句2
//代码验证
var age = prompt(‘请输入您的年龄’);
if (age >= 18) {
alert(‘我想带你去网吧偷耳机’)
} else {
alert('滚 ')
}
//5.if里面的语句1 和else 苦闷的语句2 最终只能有一个语句执行 2选1
//6. else后面直接跟大括号
判断闰年案例

var year = prompt(‘请输入年份:’)
if (year % 4 == 0 && year % 100 != 0 || year % 400== 0) {
alert(‘您输入的年份是闰年’)
} else {
alert(‘您输入的是平年’)
}
3.4 if else if 语句(多分支语句)
适合于检查多重条件
//1.多分支语句 就是利用多个条件来选择不同语句执行 得到不同的结果 多选1的过程
//2.if else if 语句是多分支语句
//3.语法规范
if (条件表达式) {
//语句1;
} else if (条件表达式2) {
//语句2;
} else if (条件表达式3) {
//语句3
} else {
//最后语句
}
//4.执行思路
//如果条件表达式1 满足就执行 语句1 执行完毕后,推出整个if 分支语句
//如果条件表达式1不满足,则判断条件表达式2 满足的话,执行语句2 以此类推
//如果上面的所有条件表达式都不成立,则执行else 里面的语句
//5.注意点
//(1)多分支语句就是多选1 最后只有一个语句执行
//(2)else if 里面的条件可以任意多个的
//(3)else if 中间有个空格
案例——判断成绩级别
//必须按照从大到小思路来写
var score = prompt(‘请输入分数:’)
if (score >= 90) { //大于等于90
alert(‘宝贝 你是我的骄傲’)
} else if (score >= 80) {
alert(‘宝贝 你已经很出色了’)
} else if (score >= 70) {
alert(‘你要加油了’)
} else if (score >= 60) {
alert (‘孩子很危险’)
} else
alert(‘熊孩子 我不想和你说话 你别学了’)
}
三元表达式
三元表达式也能做一些简单的条件选择。有三元运算符组成的式子
三元表达式 案例——数字补0
2.3for循环重复不同的代码
for循环还可以重复不同的代码,这主要是因为使用了计数器,计数器在每次循环过程中都会改变。
//for循环重复不同的代码 因为我们有计数器变量i的存在i每次循环值都会变化
//我们想要输出一个人 1~100岁
// for (var i = 1;i <= 100;i++) {
// console.log(‘宋佳硕这个人今年’+ i +‘岁了’);
// }
for (var i = 1; i <= 100; i++) {
if (i == 1) {
console.log(‘宋佳硕这个人今年1岁了,他出生了’);
} else if (i == 100) {
console.log(‘宋佳硕今年100岁了,他挂掉了’);
} else {
console.log(‘这个人今年’ + i + ‘岁了’);
}
}
2.4for循环重复某些相同操作
for循环因为有了计数器的存在,我们还可以重复执行某些操作,比如做一些算数运算。
案例1 求1-100之间所有整数的累加和
需要循环100次,我们需要一个计数器
我们需要一个存储结果的变量sum,但是初始值一定是0
核心算法:1+2+3+4… ,sum = sum + i
//for 循环重复执行某些操作 比如说我们做了100次加法运算
var sum = 0;
for (var i = 1; i <= 100; i++) {
// sum = sum + 1
sum += i;
}
console.log(sum);
for循环案例
求学生成绩案例
要求用户输入班级人数,之后依次输入每个学生的成绩,最后打印出该班级总的成绩以及平均成绩。
案例分析
弹出输入框总的班级人数(num)
依次输入学生的成绩(保存起来score),此时我们需要用到for循环,弹出的次数跟班级总人数有关系 条件表达式 i <= num
进行业务处理:计算成绩。先求总成绩(sum),之后求平均成绩(average)
弹出结果
var num = prompt(‘请输入班级的总人数:’) //num班级的总人数
var sum = 0; //求和的变量
var average = 0; //求平均值的变量
for (var i = 1; i <= num; i++) {
var score = prompt(‘请输入第’ + i + ‘个学生成绩’);
sum = sum + parseFloat(score); //因为从prompt取过来的数据是 字符串型的需要转换为数字型
}
average = sum / num;
alert(‘班级总的平均成绩是’ + sum);
alert(‘班级平均分是:’ + average);
案例 一行打印五个星星
//一行打印5个星星
// console.log(‘⭐⭐⭐⭐⭐’;
// 我们采取追加字符串的方式
// var str = '';
// for(var i =1;i<=5;i++) {
// str =str + '⭐'
// }
// console.log(str);
var num = prompt('请输入星星的个数')
var str = '';
for (var i = 1; i <= num; i++) {
str = str + '⭐';
}
alert(str);
3.双重for循环概述
很多情况下,单层for循环并不能满足我们的需求,比如我们要打印5行5列的图形、打印一个倒直角三角形等,此时我们就可以通过循环嵌套来实现。

循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,例如在for循环语句中,可以在嵌套一个for循环,这样的for循环我们称之为双重for循环。
//1.双重for循环 语法结构
for (外层的初始化; 外层的条件表达式; 外层的操作表达式) {
for (里层的初始化; 里层的条件表达式; 里层的操作表达式) {
//执行语句
}
}
//2.我们可以把里面的循环看做是外层循环的语句
//3.外层循环一次,里面的循环执行全部
//4.代码验证
for (var i = 1; i <= 3; i++) {
console.log(‘这是外层循环第’ + i + ‘次’);
for(var j=1;j<=3;J++){
console.log(‘这是里层的循环第’+j+‘次’);
}
}
3.4案例 打印5行5列星星
核心:
内层循环负责一行打印5个星星
外层循环负责打印5行
//打印5行5列星星
var str = ‘’;
for (var i = 1; i <= 5; i++) { //外层循环负责打印5行
for (var j = 1; j <= 5; j++) { //里层循环负责一行打印5颗星星
str = str + ‘⭐’;
}
//如果一行打印完毕5个星星就要另起一行 加 \n
str =str +’\n’;
}
console.log(str);

打印倒三角形案例
案例分析
一共有10行,但是每行的星星个数不一样,因此需要用到双重for循环
外层的for控制行数i,循环10次可以打印10行
内层的for控制每行的星星个数j
//打印倒三角形案例
var str = ‘’;
for (var i=1;i<=10;i++) { //外层控制行数
for (var j=i;j<=10;j++) { //里层循环打印的个数不一样 j=1
str=str+‘⭐’;
}
str +=’\n’;
}
console.log(str);
//打印正三角形案例
var str = ‘’;
for (var i=1;i<=10;i++) { //外层控制行数
for (var j=1;j<=i;j++) { //里层循环打印的个数不一样 j=1
str=str+‘⭐’;
}
str +=’\n’;
}
console.log(str);
案例 99乘法表
//打印正三角形案例
var str = ‘’;
for (var i = 1; i <= 9; i++) { //外层控制行数
for (var j = 1; j <= i; j++) { //里层循环打印的个数不一样 j=1
// 1 x 2 =2
// str=str+‘⭐’;
str += j + ‘x’ + i + ‘=’ + i * j + ‘\t’; // \t=tab键
}
str += ‘\n’;
}
console.log(str);
for循环小结
for循环可以重复执行某些相同的代码
for循环可以重复执行些许不同的代码,因为我们有计数器
for循环可以重复执行某些操作,比如算数运算符加法操作
随着需求增加,双重for循环可以做更多、更好看的效果
双重for循环,外层循环一次,内层for循环全部执行
for循环是循环条件和数字直接相关的循环
分析要比写代码重要
一些核心算法想不到,但是要学会,分析它执行过程
举一反三,自己经常总结,做一些相似的案例
4.while循环
while语句可以在条件表达式为真的前提下,循环执行指定的一段代码,知道表达式不为真时结束循环。
while语句的语法结构如下:
while(条件表达式){
//循环体代码
}
执行思路:
先执行条件表达式,如果结果为true,则执行循环体代码;如果为false,则退出循环,执行后面的代码
执行循环体代码
循环体代码执行完毕后,程序会继续判断条件表达式,如条件仍为true,则会继续执行循环体,知道循环体条件为false时,整个循环过程才会结束
//1.while 循环语法结构 while 当...的时候
// while (条件表达式) {
// //循环体
// }
//2.执行思路 当条件表达式为ture(真) 则执行循环体 否则退出我们的循环
//3.代码验证、
var num = 1; //计数器从1开始
while (num <= 100) {
console.log('你好');
num++;
}
//4.里面也应该有计数器 初始化变量
//5.里面应该也有操作表达式 完成计数器的更更新 防止死循环
while案例
打印人的一生一岁到一百岁
计算1~100之间所有整数的和
// while循环案例
//1.打印人的一生,从一岁到一百岁
// var i = 1;
// while (i <= 100) {
// console.log(‘这个人今年’+i+‘岁了’);
// i++;
// }
//2.计算1-100之间所有整数的和
// var sum = 0;
// var j = 1;
// while (j<=100) {
// sum += j;
// j++;
// }
// console.log(sum);
//3.弹出一个提示框,你爱我吗? 如果输入我爱你,就提示结束,否则,一直询问。
var message = prompt(‘你爱我吗?’);
while (message !== ‘我爱你’) {
message = prompt(‘你爱我吗?’);
}
alert(‘我也爱你哈哈’);
5.do while循环
do…while语句其实是while语句的一个变体。该循环会执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环。
do {
//循环体代码 - 条件表达式为true 时重复执行循环体代码
} while(条件表达式);
执行思路:
先执行依次循环体代码
再执行条件表达式,如果为真true,则继续执行循环体代码,如果为false,则推出循环,继续执行后面的代码
注意:先再执行循环体,再判断,我们会发现do…while循环语句执行会执行依次循环体代码
//1.do while 循环 语法结构
// do {
// //循环体
// } while (条件表达式)
//2.执行思路 跟while不同的地方在于do while 先执行一次循环体 再判断条件 如果条件表达式为真,则继续执行循环体,否则退出循环
//3.代码验证
var i = 1;
do {
console.log(‘你好’);
i++;
} while (i <=100);
// 我们的do while 循环至少执行一次
do while 案例
// do while循环案例
// 1.打印人的一生,从一岁到一百岁
// var i = 1;
// do {
// console.log(‘这个人今年’+i+‘岁了’);
// i++;
// } while (i<=100)
// 2.计算1-100之间所有整数的和
var sum = 0;
var j = 1;
do {
sum += j;
j++;
}while (j<=100)
console.log(sum);
// 3.弹出一个提示框,你爱我吗? 如果输入我爱你,就提示结束,否则,一直询问。
do {
var message = prompt(‘你爱我吗?’);
}while (message !==‘我爱你’)
alert(‘我也爱你啊’)
6.1continue关键字
continue关键字用于立即跳出本次循环,继续下一次循环(本次循环中continue之后的代码会少执行一次)
例如,吃5个包子,第3个有虫子,就扔掉第3个,继续吃第4个第5个包子,其代码实现如下:
//continue 关键字 退出当前此的循环(退出本次) 继续执行剩余次数循环
// for (var i = 1; i <= 5; i++) {
// if (i == 3) {
// continue; //只要遇见 continue就退出本次循环 直接跳到 i++
// }
// console.log('我正在吃第' + i + '个包子');
// }
//1.求1-100之间,除了能被7整除之外的整数和
var sum = 0;
for (var i = 1; i <= 100; i++) {
if(i%7==0) {
continue;
}
sum += i;
}
console.log(sum);
1.数组的概念
问:之前学习的变量,之恶能存储一个值。如果我们想存储班级中所有学生的姓名,那么该如何存储呢?
答:可以使用数组(Array)。数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。
答:数组就是指一组数据的集合,其中每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。
//普通变量一次只能存储一个值
var num = 10;
//数组一次可以存储多个值
var arr = [1,2,3,4,5];
2.创建数组
2.1数组的创建方式
JS中创建数组有两种方式:
利用new创建数组
利用数组字面量创建数组(常用)
2.2利用new创建数组
var 数组名 = new Array();
var arr = new Array(); //创建一个新的空数组
这种方式暂且了解,等学完对象再看
主要Array() , A要大写
2.3利用数组字面量创建数组
//1.使用数组字面量方式创建数组
var 数组名 = [];
//2.使用数组字面量方式创建带初始化的数组
var 数组名 = [‘小白’,‘小黑’,‘大黄’,‘瑞奇’];
数组的字面量是方括号[ ]
声明数组并赋值称为数组的初始化
这种字面量的方式也是我们以后最多使用的方式
//1.数组(Array):就是一组数据的集合 存储在单个变量下的优雅方式
//2.利用new 创建数组
var arr = new Array(); //创建了一个空的数组
//3.利用数组字面量创建数组 []
var arr = []; //创建了一个空的数组
var arr = [1,2,‘pink老师’,true];
//4.我们数组里面的数据一定用逗号分隔
//5.数组里面的数据 比如1,2… 我们称为数组元素
2.4数组元素的类型
数组中可以存放任意类型的数据,例如字符串,数组,布尔值等。
var arr = [1,2,‘pink老师’,true];
3.获取数组元素
3.1数组的索引
索引(下标):用来访问数组元素的序号(数组下标从0开始)。

数组可以通过索引来访问、设置、修改对应数组元素,我们可以通过“数组名[索引]”的形式来获取数组中的元素。
这里的访问就是获取得到的意思
//定义数组
var arrStus = [1,2,3];
//获取数组中的第2个元素
alert(arrStus[1]);
//1.数组(Array):就是一组数据的集合 存储在单个变量下的优雅方式
//2.利用new 创建数组
var arr = new Array(); //创建了一个空的数组
//3.利用数组字面量创建数组 []
var arr = []; //创建了一个空的数组
var arr1 = [1,2,‘pink老师’,true];
//4.我们数组里面的数据一定用逗号分隔
//5.数组里面的数据 比如1,2… 我们称为数组元素
//6.获取数组元素 格式 数组名[索引号] 索引号从0开始
console.log(arr1);
console.log(arr1[2]); //pink老师
console.log(arr1[3]); //true
课堂练习:数组练习
定义一个数组,里面存放星期一…直到星期日(共7天),在控制台输出星期日
var arr2 = [‘星期一’,‘星期二’,‘星期三’,‘星期四’,‘星期五’,‘星期六’,‘星期日’]
console.log(arr2[6]);
4.遍历数组
问:数组中的每一项我们怎么取出来?
答:可以通过“数组名[索引号]”的方式一项项取出来

问:怎么把数组里面的元素全部取出来?
规律:
从代码中我们可以发现,从数据中取出每一个元素时,代码是重复的,有所不一样的是索引值在递增答案就是 循环
遍历:就是吧数组中每个元素从头到尾访问一次(类似我们每天早上学生的点名)
//遍历数组:就是把数组的元素从头到尾访问一次
var arr = [‘red’,‘green’,‘blue’]
for(var i = 0;i < 3;i++) {
console.log(arr[i]);
}
//1.因为我们的数组索引号从0开始,索引 i 必须是从零开始 i<3
//2.输出的时候 arr[i] i计数器当索引号使用
课堂案例1:遍历数组
请将[‘关羽’,‘张飞’,‘马超’,‘赵云’,‘黄忠’,‘刘备’,‘姜维’,];数组里面的元素依次打印到控制台
var arr = [‘关羽’,‘张飞’,‘马超’,‘赵云’,‘黄忠’,‘刘备’,‘姜维’,];
for(var i = 0;i < 7;i++ ){
console.log(arr[i]);
}
4.1数组的长度
使用“数组名.length”可以访问数组元素的数量(数组长度)。
//数组长度 数组名.length
var arr = [‘关羽’,‘张飞’,‘马超’,‘赵云’,‘黄忠’,‘刘备’,‘姜维’,];
for(var i = 0;i < 7;i++ ){
console.log(arr[i]);
}
console.log(arr.length);
for(var i = 0;i < arr.length;i++ ){
console.log(arr[i]);
}
//1.数组的长度是元素的个数 不要跟索引号混淆
//2.arr.length 动态渐层祖元素的个数
小题
1.什么是遍历?.
遍历就是把我们的数组从头到尾访问一次
2.我们通过什么来遍历数组里面的元素?
for循环
3.for里面的i是什么?当什么使用?for里面的数组元素怎么写?
i是计数器 当索引号使用 arr[i]是数组元素 第i个数组元素
4.怎么获取数组的长度
.length
5.数组的索引号和数组的长度有什么关系?
没有任何关系 索引号从0开始的 数组长度是元素的个数
课堂案例2:数组求和平均值
求数组[2,4,1,7,4]里面所有元素的和以及平均值。
先声明一个求和的变量
遍历这个数组,把里面每个个数族元素加到sum里面
用求和变量sum除以数组的长度就可以得到数组的平均值。
var sum = 0;
var average = 0;
var arr= [2,4,1,7,4];
for(var i = 0;i < arr.length;i++){
sum += arr[i]; //我们加的是数组元素arr[i] 不是计数器i
}
average = sum / arr.length;
console.log(sum,average); //想要输出多个变量用逗号分隔
课堂案例3:求最大值
声明一个保存最大元素的变量max
默认最大值可以去数组中的第一个元素
遍历这个数组,把里面每个数组和max相比较
如果这个数组大于max就把这个数组元素存到max里面,否则继续下一轮比较
输出max
var arr = [2, 6, 1, 77, 52, 25, 7];
var max = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i]
}
}
console.log(‘该数组里面的最大值’+ max);
课堂案例4:数组转换为分割字符串
要求:将数组[‘red’,‘green’,‘blue’,‘pink’,]转换为字符串,并且用|或其他符号分割
输出:‘red|green|blue|pink|’
案例分析:
需要一个新变量用于存放转换完的字符串str
遍历原来的数组,分别把里面数据取出来,加到字符串里面
同时在后面多加一个分隔符
var arr = [‘red’,‘green’,‘blue’,‘pink’,];
var str = ‘’;
var sep =’!’;
for(var i = 0;i < arr.length;i++){
str += arr[i]+sep;
}
console.log(str);
5.数组中新增元素
可以通过修改length长度以及索引号增加数组元素
5.1通过修改length长度新增数组元素
可以通过length长度来实现数组扩容的目的
length可读写的
//1.新增数组元素 通过修改length长度
var arr = [‘red’,‘green’,‘blue’];
console.log(arr.length);
arr.length = 5; //把我们数组长度修改为5 里面应该有5个元素
console.log(arr);
console.log(arr[3]); //undefined
console.log(arr[4]); //undefined
其中索引号4,5,6的空间没有给值,就是声明变量未给值,默认值就是undefined
5.2通过修改数组索引号新增数组元素
可以通过修改数组索引方式追加数组元素
不能直接给数组名赋值,否则会覆盖掉以前的数据
//2.新增数组元素 修改索引号 追加数组元素
var arr1 = [‘red’,‘green’,‘blue’];
arr1[3] = ‘pink’; //追加数组元素
console.log(arr1);
arr1[0] = ‘yellow’; //这里是替换原来的数组元素
console.log(arr1);
arr1 = ‘有点意思’;
console.log(arr1); //不要直接给数组赋值 数组名赋值 否则里面的数组元素都没有了
这种方式也是我们最常用的一种方式。
课堂案例:数组新增元素
新建一个数组,里面存放(1-10)
案例分析
通过循环来追加数组
声明一个空数组arr。
循环中的计数器i 可以作为数组元素存入
由于数组的索引号从0开始的 因此计数器是从0开始更合适 存入的数组元素要加1
var arr = [];
for (var i = 0;i <= 99;i++) {
// arr = i; //不要直接给数组名赋值 否则以前的元素都会被覆盖
arr[i] = i + 1;
}
console.log(arr);
课堂案例:筛选数组
要求:将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组
案例分析
1.声明一个新的数组用于存放新数据newArr
2.遍历原来的旧数组,找出大于等于10的元素
3.依次存放新数组newArr
var newArr=[];
j = 0;
var arr = [2,0,6,1,77,0,52,0,25,7];
for (var i = 0;i <= 10;i++) {
if(arr[i] >= 10) {
//新数组索引号应该从0开始 依次递增
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
// 方法2
var newArr=[];
// 刚开始newArr.length 就是0
var arr = [2,0,6,1,77,0,52,0,25,7];
for (var i = 0;i <= 10;i++) {
if(arr[i] >= 10) {
//新数组索引号应该从0开始 依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
1.函数的概念
在JS里面,可能会定义非常多的相同代码或者相似的代码,这些代码可能需要大量重复使用。
虽然for循环语句也能实现一些简单的重复操作,但似乎比较具有局限性,此时我们就可以使用JS中的函数
函数:就是封装了一段可被重复调用执行的代码块。通过此代码可以实现大量代码的重复使用

2.函数的使用
函数在使用时分为两步:声明函数和调用函数。
2.1声明函数
//声明函数
function 函数名() {
//函数体代码
}
function是声明函数的关键字,必须小写
由于函数一般是为了实现某个功能才定义的,所以通常我们将函数名命名为动词,比如getSum
2.2调用函数
//调用函数
函数名(); //通常调用函数名来执行函数体代码
调用的时候千万不要忘记加小括号
口诀:函数不调用,自己不执行。
注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。
2.3函数的封装
函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供了一个简单的函数接口
简单理解:封装类似于将电脑整合组装到机箱中(类似打包快递)
//函数使用分为两步:声明 和调用
//1.声明函数
// function 函数名() {
// //函数体(函数代码)
// }
function sayHi() {
console.log(‘hi’);
}
//(1)function 声明函数的关键字 全部小写
//(2)函数是做某件事情 函数名一般是动词 sayHi
//(3)函数不调用自己不执行
//2.调用函数
// 函数名();
sayHi();
//调用函数的时候千万不要忘了加小括号
3.函数的参数
3.1形参和实参
在声明函数时,也可以在函数名后面的小括号中添加一些参数,这些参数称之为形参,而在调用该函数时,同样也需要传递相应的参数,这些参数称之为实参。
参数 | 说明
形参 | 形式上的参数 函数定义的时候 传递的参数 当前并不知道是什么
实参 | 实际上的参数 函数调用的时候传递的参数 实参是传递给形参的
参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去
//1.函数可以重复相同的代码
function cook() {
console.log(‘酸辣土豆丝’);
}
cook();
//2.我们可以利用函数的参数实现函数重复不同的代码
function 函数名(形参1,形参2) { //在声明函数的小括号里面是 形参 (形式上的参数)
}
函数名(实参1,实参2...) //在函数调用的小括号里面是实参
// 3.形参和实参的执行过程
function cook(aru) { //形参是接收实参的 aru = '酸辣土豆丝'形式类似于一个变量
console.log(aru);
}
cook('算辣土豆丝')
cook('大肘子')
//4.函数的参数可以有,也可以个数不限
案例-利用函数求任意两个数的和以及累加和
//1.利用函数求任意两个数的和
function getSum(num1, num2) {
console.log(num1 + num2);
}
getSum(1, 3);
getSum(3,8);
//2.利用函数求任意两个数之间的和
function getSum(start,end) {
var sum = 0;
for(var i = start;i <= end;i++) {
sum +=i;
}
console.log(sum);
}
getSum(1,100);
getSum(1,10);
//1.注意点
//(1)多个参数之间用逗号隔开
//(2)形参可以看作是不用声明的变量
3.3函数行参个数不匹配问题
参数个数 | 说明
形参个数等于形参个数 | 输出正确结果
实参个数多于形参个数 | 只取到形参的个数
实参个数小于形参个数 | 多的形参定义为undefined 结果为NaN
//函数形参实多个数匹配
function getSum(num1,num2) {
console.log(num1 + num2);
}
//1.如果实参的个数和形参的个数一直 则正常输出结果
getSum(1,2);
//2.如果实参的个数多于形参的个数 会取到形参的个数
getSum(1,2,3);
//3.如果实参的个数小于形参的个数 多余的形参定义为undefined 最终结果就是NaN
// 形参可以看作不用声明的变量 num2 是一个变量但是没有接收 结果就是undefined
getSum(1); //Nan
//建议 我尽量让实参的个数和形参相匹配
注意:在Javascript,形参的默认是undefined
3.4函数的参数小结
函数可以带参数也可以不带参数
声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined
调用函数的时候,函数名括号是实参
多个参数中间用逗号分隔
形参的个数可以和实参个数不匹配,但是结果不可预计 我们尽量要匹配
4.函数的返回值
4.1return语句
有的时候,我们会希望函数值返回给调用这,此时通过return语句就可以实现。
//1.函数是做某前世或者实现某种功能、
// function cook(aru) {
// console.log(aru);
// }
// cook(‘大肘子’)
// //2.函数的返回值格式
// function 函数名() {
// return; //需要返回的结果
// }
// 函数名();
//(1)我们函数只是实现某种功能,最终结果需要返回给函数的调用者函数名() 通过return实现
//(2)只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果
//3.代码验证
function getResult() {
return 666; //实现赋值操作
}
getResult(); //getResult() = 666
console.log(getResult());
// function cook(aru) {
// return aru;
// }
// console.log(cook('大肘子'));
//4.求任意两个数的和
function getSum(num1,num2) {
return num1 + num2;
}
console.log(getSum(1,2));
案例1:利用函数求任意两个数最大值
//利用函数 求两个数的最大值
function getMax(num1,num2) {
// if(num1 > num2) {
// return num1;
// } else {
// return num2;
// }
return num1 > num2 ? num1 : num2; //三元运算符
}
console.log(getMax(1,3));
console.log(getMax(11,3));
案例2:利用函数求任意一个数组中的最大值
求数组[5,2,99,101,67,77]
function getArrMax(arr) { //arr接收一个数组 arr = var re = [5,2,99,101,67,77]
var max = arr[0];
for(var i = 1;i <= arr.length; i++) {
if(arr[i] > max) {
max =arr[i];
}
}
return max;
}
// getArrMax([5,2,99,101,67,77]); //实参是一个数组送过去
// 在我们实际开发里面 我们经常用一个变量来接收 函数的返回结果 使用更简单
// var re = getArrMax([5,2,99,101,67,77]);
var re = getArrMax([5,2,99,101,67,77,9999,888]);
console.log(re);
4.2return 终止函数
return语句之后的代码不被执行
//函数返回值注意事项
//1.return 终止函数
function getSum(num1, num2) {
return num1 + num2; //return 后面的代码不被执行
alert('我是不会被执行的')
}
console.log(getSum(1, 2));
//2.return 只能返回一个值
function fn(num1, num2) {
return num1, num2; //返回的结果是最后一个值
}
console.log(fn(1, 2));
//3.我们求任意两个数 加减乘除结果
function getResult(num1, num2) {
return [num1 + num2, num1 - num2, num1 * num2, num1 / num2]
}
var re = getResult(1,2); //返回的是一个数组
console.log(re);
4.4函数没有return返回undefined
函数都是有返回值的:
如果有return 则返回的是return 后面的值
如果函数没有return 则返回undefined
4.5break,continue,return的区别
break:结束当前的循环体(如for、while)
continue:跳出本次循环,继续执行下次循环(如for、while)
return:不仅可以推出循环,还能够返回return语句中的值,同时还可以结束当前的函数体的代码
通过榨汁机看透函数

当我们不确定有多少个参数的时候,可以用arguments来获取。在Javascript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
具有length属性
按索引方式存储数据
不具有数组的push,pop等方法
// arguments 的使用 只有函数才有 arguments对象 而且是每个函数都内置好了这个arguments
function fn() {
// console.log(arguments); //里面存储了所有传递
console.log(arguments.length);
console.log(arguments[2]);
//我们可以按照数组的方式遍历数组arguments
for(var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
fn(1,2,3);
fn(1,2,3,4,5);
// 伪数组 并不是真正意义上的数组
// 1.具有数组length长度属性
// 2.按照索引方式进行存储
// 3.他没有真正数组的一些方法 pop() push()等
案例-利用函数求任意个数的最大值
// 利用函数求任意个数的最大值
function getmax() { ?/arguments = [1,2,3]
var max = arguments[0];
for(var i = 1;i
max =arguments[i];
}
}
return max;
}
console.log(getMax(1,2,3));
console.log(getMax(1,2,3,4,5));
console.log(getMax(11,2,34,444,5,100));
案例1:利用函数封装方式,翻转任意一个数组
// 利用函数翻转任意数组 reverse 翻转
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i–) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1, 2, 3, 4, 6, 9])
console.log(arr1);
var arr2 = reverse([‘red’, ‘pink’, ‘blue’]);
console.log(arr2);
函数封装冒泡排序

//利用函数冒泡排序 sort排序
function sort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
案例3:判断闰年
要求:输入一个年份,判断是否是闰年(闰年:能够被4整除并且不能被100整除,或者能被400整除)
//利用函数判断闰年
function isRunYear(year){
//如果是闰年我们返回true 否则 返回 false
var flag = false;
if(year % 4 == 0 && year % 100 !=0 || year % 400 ==0) {
flag = true;
}
return flag;
}
console.log(isRunYear(2000));
console.log(isRunYear(1999));
函数可以调用另外一个函数
因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。
//函数可以相互调用的
function fn1() {
console.log(11);
fn2(); //在fn1函数里面调用了 fn2 函数
}
fn();
function fn2() {
console.log(22);
}
输出2月份天数
//用户输入年份,输出当前年份2月份的天数
function backDay() {
var year = prompt(‘请输入年份’);
if(isRunYear(year)){ //调用函数需要加小括号
alert(‘当前年份是闰年2月份有29天’)
} else {
alert(‘当前是平年2月份有28天’);
}
}
backDay();
//判断是否为闰年的函数
function isRunYear(year){
//如果是闰年我们返回true 否则 返回 false
var flag = false;
if(year % 4 == 0 && year % 100 !=0 || year % 400 ==0) {
flag = true;
}
return flag;
}
函数两种声明方式
//函数的两种声明方式:
// 1.利用函数关键字自定义函数 (命名函数)
function fn() {
}
fn();
//2.函数表达式 (匿名函数)
// var 变量名 = function(){};
var fun = function(aru){
console.log('我是函数表达式');
console.log(aru);
}
fun('pink老师');
//(1)fun 是变量名 不是函数名
//(2)函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而 函数表达式里面存的是函数
//(3)函数表达式也可以进行传递参数
1.1作用域概述
通常来讲,一段程序中所用到的名字并不总是有效和可用的,而限定这个名字的可用性代码范围就是这个给名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
//1.JavaScript作用域:就是代码名字(变量)在某个范围内作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突
//2.js作用域(es6)之前:全局作用域 局部作用域
//3.全局作用域:整个script标签 或者是一个单独的js文件
var num = 10;
console.log(num);
//4.局部作用域 (函数作用域)在函数内部就是局部作用域 这个代码的名字只在函数内部起作用
function fn() {
//局部作用域
var num = 20;
console.log(num);
}
fn();
2.1变量作用域的分类
在JavaScript中,根据作用域的不同,变量可以分为两种:
全局变量
局部变量
2.2全局变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)
全局变量在代码的任何位置都可以使用
在全局作用域下var声明的变量是全局变量
特殊情况在函数内不使用var声明的变量也是全局变量(不建议使用)
2.2局部变量
在局部作用域下的变量叫做局部变量(在函数内部定义的变量)
局部变量只能子啊该函数内部使用
在函数内部var 声明的变量是局部变量
函数的形参实际上就是全局变量
2.3全局变量和局部变量区别
全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
局部变量:只在函数内部使用,档期所在的代码被执行时,会被初始化;当代码运行结束后 ,就会被销毁,因此更节省空间
//变量的作用域:根据作用域的不同我们变量分为全局变量和局部变量
//1.全局变量:在全局作用下的变量 在全局下都可以使用
//如果在函数内部 没有声明直接赋值的变量也属于全局变量
var num = 10; //num就是一个全局变量
console.log(num);
function fn() {
console.log(num);
}
fn();
console.log(aru);
//2.局部变量 在局部作用域下的变量 后者在函数内部的变量就是 局部变量
//注意:函数的形参也可以看作是局部变量
function fun(aru) {
var num1 = 10; //num1就是局部变量 只能在函数内部使用
num2 = 20;
}
fun();
// console.log(num1);
// console.log(num2);
//3.从执行效率来看全局变量和局部变量
// (1)全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
// (2)局部变量 当我们程序执行完毕就会被销毁,比较节省资源
1.4JS没有块级作用域
//JS没有块级作用域 js的作用域:全局作用域 局部作用域 现阶段JS没有块级作用域
//我们js 也是在 es6 的时候新增的块级作用域
//块级作用域 {} if{} for{}
//java
// if(xx) {
// int num = 10;
// }
// 外面的是不能调用num的
if(3<5) {
var num = 10;
}
console.log(num);
3.作用域链
只要是代码,就至少有一个作用域
写在函数内部的局部作用域
如果函数中还有函数,那么在这个作用域中就可以诞生一个作用域
根据内部函数可以访问外部函数变量的这种机制,用链式查找决定那些数据能被内部函数访问,就称作作用域链
自己理解
从要求输出结果往上一层进行查找 如果有多个类名相同 找最近(里输出最近那个)
//作用域链 :内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值 这种结构我们称为作用域链 就近原则
var num = 10;
function fn(){ //外部函数
var num = 20;
function fun() { //内部函数
console.log(num);
}
fun(); //调用才会被执行
}
fn();
案例1:结果是几?
// 案例1:结果是几?
function f1() {
var num = 123;
function f2() {
console.log(num);
}
f2();
}
var num = 456;
f1();

JavaScript代码是由浏览器中的javascript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行。
//1问
console.log(num);
//2问
console.log(num); //undefined 坑1
var num = 10;
//相当于执行了以下代码
// var num;
// console.log(num);
// num = 10;
//3问
fn();
function fn() {
console.log(11);
}
//4问
fun(); //报错 坑2
var fun = function() {
console.log(22);
}
//函数表达式 调用必须下载函数表达式下面
//相当于执行了以下代码
var fun;
fun();
fun = function(){
console.log(22);
}
//1.我们js引擎运行分为两步:预解析 代码执行
//(1).预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
//(2).代码执行 按照代码书写顺序从上往下执行
//2.预解析 分为 变量预解析(变量提升)和 函数预解析(函数提升)
//(1)变量提升 就是把所有的变量声明提升到当前作用域最前面 不提升赋值操作
//(2)函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
1.对象
1.1什么是对象?
现实生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人可以说是“对象”,一个数据库、一张网页、一个远程服务器的链接也可以是“对象”。
在javascript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成的。
属性:事物的特征,在对象中用属性来表示(常用名词)
方法:事物的行为,在对象中用方法来表示(常用动词)
2.为什么需要对象
保存一个值,可以使用变量。保存多个值(一组值)时,可以使用数组。如果要保存一个人的完整信息呢?
例如,将“张三丰”的个人信息保存在数组中的方式为:
var arr = [‘张三丰’,‘男’,128,154]
JS中的对象表达结构更清晰更强大。张三丰的个人信息在对象的表达结构如下:
张三丰.姓名 = ‘张三丰’;
张三丰.性别 = ‘男’;
张三丰.年龄 = 128;
张三丰.身高 = 154;
person.name = ‘张三丰’;
person.sex = ‘男’;
person.age = 128;
person.height = 154;
在javascript中,现阶段我们采用三种方式创建对象(object):
利用字面量创建对象
利用new object创建对象
利用构造函数创建对象
2.1利用字面量创建对象
对象字面量:就是花括号{}里面包含了表达这个具体事物(对象)的属性和方法。
{}里面采取键值对的形式表示
键:相当于属性名
值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型、函数等类型)
对象的调用
对象里面的属性调用:对象.属性名,这个小点.就理解为 的
对象里面的属性的另一种调用方式:对象[‘属性名’],注意方括号里面的属性必须加引号,我们后面会用
对象里面的方法调用:对象.方法名(),注意这个方法后面一定加括号
//利用对象字面量创建函数 {}
// var obj = {}; //创建了一个空的对象
var obj = {
uname:‘蜡笔小新’,
age:18,
sex:‘男’,
sayHi:function(){
console.log(‘hi’);
}
}
//(1)里面的属性或者方法我们采取键值对的形式
// (2) 多个属性或者方法中间用逗号隔开
// (3) 方法后面跟的是一个匿名函数
//2.使用对象
//(1).调用对象的属性 我们采取 对象名.属性名 .我们理解为 的
console.log(obj.uname);
//(2).调用还有一种方法 对象名[‘属性名’]
console.log(obj[‘age’]);
//(3).调用对象的方法 sayHi 对象名.方法名() 千万别忘记加上小括号
obj.sayHi();
案例
var obj = {
uname:‘可可’,
type:‘阿拉斯加犬’,
age:5,
color:‘棕红色’,
skill:function(){
console.log(‘汪汪汪’+‘演电影’);
}
}
console.log(obj.uname);
console.log(obj.type);
console.log(obj.age);
console.log(obj[‘color’]);
obj.skill();
变量、属性、函数、方法的总结
变量:单独声明赋值,单独存在
属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征 比如var obj = {}
函数:单独存在的,通过”函数名()“的方式就可以调用
方法:对象里面的函数称为方法,方法不需要声明,使用”对象.方法名()“的方式就可以调用,方法用来描述该对象的行为和功能
//变量、属性、函数、方法的区别
//1.变量和数学的相同点 他们都是用来存储数据
var num = 10;
var obj = {
age:18,
fn:function() { //方法
}
}
function fn(){ //函数
}
console.log(obj.age);
// console.log(age);
//变量 单独声明并赋值 使用的时候直接写变量名 单独存在
//属性 在对象里面不需要声明的 使用的时候必须是 对象.属性
//2.函数和方法的相同点 都是实现某种功能 做某件事
//函数是单独声明 并且调用的 函数名() 单独存在的
//方法 在对象里面 表用的时候 对象.方法()
跟我们前面学习的 new Array()原理一致
//利用new Object创建对象
var obj = new Object(); //创建了一个空的对象
obj.uname = ‘张三丰’;
obj.age = 18;
obj.sex = ‘男’;
obj.sayHi = function() {
console.log(‘hi’);
}
//(1)我们是利用等号=赋值的方法 添加对象的属性和方法
// (2) 每个属性和方法用 分号;结束
console.log(obj.uname);
console.log(obj[‘sex’]);
obj.sayHi();
案例-按照要求写出对象
var obj = new Object();
obj.uname = ‘漩涡鸣人’;
obj.from = ‘木叶村’;
obj.sex = ‘男’;
obj.age = 19;
obj.skill = function() {
console.log(‘影分身术’+‘螺旋丸’);
}
console.log(obj.uname);
console.log(obj[‘from’]);
console.log(obj.sex);
console.log(obj[‘age’]);
obj.skill();
2.3利用构造函数创建对象
//我们为什么需要使用构造函数
//就是因为我们前面两种创建对象的方式一次只能创建一个对象
var ldh = {
uname:‘刘德华’,
age:55,
sing:function(){
console.log(‘冰雨’);
}
}
var zxy = {
uname:‘张学友’,
age:58,
sing:function(){
console.log(‘李香兰’);
}
}
//因为我们一次创建一个对象 里面很多属性和方法v是大量相同的 我们只能复制
//因此我们可以利用函数的方法 重复这些相同的代码 我们把这个函数称为构造函数
//又因为这个函数不一样 里面封装的不是普通代码 而是 对象
//构造函数 就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中的一些公共的属性和方法抽取出来,然后封装这个函数里面。
//利用构造函数创建对象
//我们需要创建四大天王的对象 相同的属性:名字 年龄 性别 相同的方法:唱歌
//构造函数的语法格式
// function 构造函数名(){
// this.属性 = 值;
// this.方法 = function(){}
// }
// new 构造函数名();
function Star(uname,age,sex){
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var ldh = new Star(‘刘德华’,18,‘男’); //调用函数返回的是一个对象
// console.log(typeof ldh);
console.log(ldh.name);
console.log(ldh[‘age’]);
ldh.sing(‘冰雨’);
var zxy = new Star(‘张学友’,19,‘男’);
console.log(zxy.name);
console.log(zxy[‘age’]);
zxy.sing(‘李香兰’);
//1.构造函数名字首字母要大写
//2.我们构造函数不需要return 就可以返回结果
//3.我们构造函数必须使用 new
//4.我们只要new Star() 调用函数就创建了一个人对象 ldh {}
//5.我们的属性和方法前面必须添加this
案例
function Star(uname,type,blood){
this.name = uname;
this.type = type;
this.blood = blood;
this.attack = function(attack){
console.log(attack);
}
}
var hy = new Star(‘后羿’,‘射手型’,100);
console.log(hy.name);
console.log(hy[‘type’]);
console.log(hy.blood);
hy.attack(‘远程’);
var lp = new Star('廉颇','战士型',500);
console.log(lp.name);
console.log(lp['type']);
console.log(lp['blood']);
lp.attack('近战')
构造函数和对象的区别:
2.4构造函数和对象
构造函数,如Stars(),抽象了对象的公共部分,封装了对象的公共部分,封装了函数里面,他泛指某一大类(class)
创建对象,如new Stars(),特指某一个,通过new关键字创建对象的过程我们也称为对象实例化

new在执行时会做四件事情:
1.在内存中创建了一个新的空对象
2.让this指向这个新的对象
3.执行构造函数里面的代码,给这个新对象添加属性和方法。
4.返回这个新对象(所以构造函数里面不需要return)
// new 关键字执行过程
//1.new 构造函数可以在内存中创建了一个空的对象
//2.this就会指向刚才创建的空对象
//3.执行构造函数里面的代码给这个空对象添加属性和方法
//4.返回这个对象
function Star(uname,age,sex){
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var ldh = new Star(‘刘德华’,18,‘男’);
for …in语句用于对数组或者对象的属性进行循环操作。
//遍历对象
var obj = {
name:‘pink老师’,
age:18,
sex:‘男’,
fn:function(){} //fn方法名
}
// console.log(obj.name);
// console.log(obj.age);
// console.log(obj.sex);
//for…in遍历我们对象
// for (变量 in 对象) {
// }
for(var k in obj) {
console.log(k); //k 变量 输出 得到的是 属性名
console.log(obj[k]); //obj[k] 得到的是 属性值
}
//我们使用for in 里面的变量 我们喜欢写 k 或者 key
对象可以让代码更清晰
对象复杂数据类型object
本质:对象就是一组无序的相关属性和方法的集合
构造函数就繁殖某一大类,比如苹果,不管是红色苹果还是绿色苹果,统称为苹果
对象实例特指一个事物
for…in语句用于对对象的属性进行循环操作。
作业案例
1.创建一个电脑对象,该对象要有颜色、重量、品牌、型号,可以看电影 听音乐 打游戏 敲代码
var obj = new Object(‘电脑’);
obj.uname = ‘惠普’;
obj.color = ‘black’;
obj.model = ‘暗夜精灵’;
obj.weight = ‘2010’
obj.Gn = function() {
console.log(‘看电影’,‘听音乐’,‘敲代码’);
}
for(var k in obj){
console.log(obj[k]);
}
2.创建一个按钮对象,该对象中需要包含宽、高,背景颜色和点击行为
没写出来
function Star(kind,wide,tall,background){
this.kind = kind;
this.wide = wide;
this.tall = tall;
this.background = background;
this.behavior = function(behavior){
console.log(‘旋转’);
}
}
new Star(‘按钮’,150,150,‘pink’);
3.创建一个车的对象,该对象要有重量,颜色、牌子、可以载人、拉货和耕田
var che = new Object();
che.uname = ‘奔驰大G’;
che.weight = 2050;
che.brandname = ‘奔驰’;
che.way = function() {
console.log(‘载人’);
console.log(‘拉货’);
console.log(‘耕地’);
}
for(var k in che){
console.log(che[k]);
}
1.内置对象
javascript中的对象分为3种:自定义对象、内置对象、浏览器对象
前面两种对象是JS基础内容,属于ECMAScript;第三个浏览器对象属于我们JS独有的
内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
内置对象最大的优点就是帮助我们快速开发
JavaScript提供了多个内置对象:Match、Date、Array、String等
2.1MDN
学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过MDN/W3C来查询。
Mozilla开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括Html、CSS和万维网以及HTML5应用的API。
MDN:https://developer.mozilla.org/zh-CN/
2.查文档
2.2如何学习对象中的方法
1.查阅该方法的功能
2.查看里面参数的意义和类型
3.查看返回值的意义和类型
4.通过demo进行测试
Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。
Math 用于 Number 类型。它不支持 BigInt。
与其他全局对象不同的是,Math 不是一个构造器。Math 的所有属性与方法都是静态的。引用圆周率的写法是 Math.PI,调用正余弦函数的写法是 Math.sin(x),x 是要传入的参数。Math 的常量是使用 JavaScript 中的全精度浮点数来定义的。
//Math数学对象 不是一个构造函数,所以我们不需要new 来调用 而是直接使用里面的属性和方法即可
console.log(Math.PI); //一个属性 圆周率
console.log(Math.max(1,99,3)); //99
console.log(Math.max(-1,-10)); //-1
console.log(Math.max(1,99,‘pink老师’)); //如果里面有非数字 返回NAN
console.log(Math.max()); //-Infinity
案例
利用对象封装自己的数学对象 里面有PI最大值和最小值
// 利用对象封装自己的数学对象 里面有PI最大值和最小值
var myMath = {
PI: 3.141592653,
max: function () {
var max = arguments[0]; //arguments可以接收你传递过来的任何实参
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
},
min: function () {
var min = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
}
}
console.log(myMath.PI);
console.log(myMath.max(1,5,9));
console.log(myMath.min(1,5,9));
3.1Math概述
Math对象不是构造函数,它具有数学和函数的属性和方法。跟数学相关的运算(求绝对值,整、最大值等)可以使用Math中的成员。
Math.PI //圆周率
Math.floor() //向下取整
Math.ceil() //向上取整
Math.round() //四舍五入版 就近取整 注意-3.5 结果是 -3
Math.abs() //绝对值
Math.max()/Math.min() //求最大和最小值
//1.绝对值方法
console.log(Math.abs(1)); //1
console.log(Math.abs(-1)); //1
console.log(Math.abs(’-1’)); //隐式转换 会把字符串型 -1 转换成数字型
console.log(Math.abs(‘pink’)); //NaN
//2.三个取整方法
// (1)Math.floor() 向下取整 往最小取值
console.log(Math.floor(1.2)); //1
console.log(Math.floor(2.2)); //2
// (2)Math.ceil() ceil 天花板 向上取整
console.log(Math.ceil(1.2)); //2
console.log(Math.ceil(2.2)); //3
// Math.round()四舍五入 就近取整 其他数字都是四舍五入,但是 .5 特殊 他往大了取
console.log(Math.round(1.2)); //1
console.log(Math.round(2.5)); //3
console.log(Math.round(-1.1)); //-1
console.log(Math.round(-1.5)); //这个结果是-1 因为如果按照正的来算应该是2 因为负的他会往大的取 1比2 1大
3.2随机数方法random()
Math.floor(Math.random() * (max - min + 1)) + min;
//Math对象随机数方法 random() 返回随机一个小数 0 =< x < 1
//2.这个方法里面不跟参数
//3.代码验证
// console.log(Math.random());
//4.我们想要得到两个数之间的随机整数 并且 包含这2个整数
// Math.floor(Math.random() * (max - min + 1)) + min;
function getRandom(max,min) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(getRandom(1,10));
//5.随机点名
var arr = [‘张三’,‘张三丰’,‘张三疯子’,‘李四’,‘李思思’];
// console.log(arr[]);
console.log(arr[getRandom(0,arr.length-1)]);
//案例 猜数字游戏
//猜数字游戏
//1.随机生成一个1-10的整数 我们需要用到 Math.random()方法
//2.需要一直猜到正确为止,所以需要一直循环
//3.while 循环更简单
//4.核心算法:使用if else if多分支语句来判断大于、小于、等于、
// function getRandom(max, min) {
// return Math.floor(Math.random() * (max - min + 1)) + min;
// }
// var random = getRandom(1, 10);
// while (true) { //死循环
// var num = prompt(‘你来猜?输入一个1~10之间一个数字’);
// if (num > random) {
// alert(‘你猜大了’);
// } else if (num < random) {
// alert(‘你猜小了’);
// } else {
// alert(‘你好帅哦,猜对了’);
// break;退出整个循环结束程序
// }
// }
//要求用户猜 1~50之间的一个数组 但只有10次机会
function getRandom(max, min) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var random = getRandom(1, 50);
for (var i=1;i<=10;i++) { //死循环
var num = prompt(‘你来猜?输入一个1~50之间一个数字’);
if (num > random) {
alert(‘你猜大了’);
} else if (num < random) {
alert(‘你猜小了’);
} else {
alert(‘你好帅哦,猜对了’);
break;//退出整个循环结束程序
}
if (i==10){
alert(‘抱歉机会用完’);
}
}
4.1Date概述
Date对象和Math对象不一样,他是一个构造函数,所以我们需要实例化后才能使用
Date实例用来处理日期和时间
4.2Date()方法的使用
1.获取当前时间必须实例化
var now = new Date(); //不给值就显示现在的时间
consol.log(now);
2.Date()构造函数的参数
如果括号里面有时间,就返回参数里面的时间。例如日期格式字符串为’2019-5-1’,就可以写成new Date(‘2019-5-1’)或者new Date(‘2019/5/1’)
//Date() 日期对象 是一个构造函数 必须使用new 来调用创建我们的日期对象
var arr = new Array(); //创建一个数组对象
var obj = new Object(); //创建了一个对象实例
//1. 使用Date 如果没有参数 就返回当前系统的当前参数
var date = new Date();
console.log(date);
//2. 参数常用的写法 数字型 2019,10,01 或者是 字符串型 ‘2019-10-1 8:8:8’
var date1 = new Date(2021,11,13);//写的是11月 返回输出12月 字符串不会出现这种情况
console.log(date1);
var date2 = new Date(‘2021-11-13 1:05:32’);
console.log(date2);
4.3日期格式化
我们想要2019-8-8 8:8:8格式的日期,要怎么办?
需要获取日期指定的部分,所引我们要手动的得到这种格式。
方法名 | 说明 | 代码
getFullYear() | 获取当年 | dObj.getFullYear()
getMonth() | 获取当月(0-11) | dObj.getMonth()
getDate() | 获取当天日期 | dObj.getDate()
getDay() | 获取星期几(周日0 到周六6) | dObj.getDay()
getHours() | 获取当前小时 | dObj.getHours()
getMinutes() | 获取当前分钟 | dObj.getMinutes()
getSeconds() | 获取当前秒钟 | dObj.getSeconds()

4.3格式化日期时分秒
//格式化 时分秒
var date = new Date();
console.log(date.getHours()); //时
console.log(date.getMinutes()); //分
console.log(date.getSeconds()); //秒
// 要求封装一个函数返回当前的时分秒 格式 08:08:08
function getTime() {
var time = new Date();
var h = time.getHours();
h = h < 10 ? ‘0’ + h : h;
var m = time.getMinutes();
m = m < 10 ? ‘0’ + m : m;
var s = time.getSeconds();
s = s < 10 ? ‘0’ + s : s;
return h + ‘:’ + m + ‘:’ + s;
}
console.log(getTime());
4.4获取日期的总的毫秒形式
Date对象是基于1970年1月1日(世界标准时间)起的毫秒数
我们经常利用总的毫秒数来计算时间,因为他更准确
//获得Date总的毫秒数(时间戳) 不是当前时间的毫秒数 而是距离1970年的1月1日过来多少毫秒数
//通过valueOf() getTime()
var date = new Date ();
console.log(date.valueOf()); //就是我们现在时间距离1970年1月1日 总的毫秒数
console.log(date.getTime());
// 2.简单写法 (最常用的写法)
var date1 = +new Date(); //返回就是总的毫秒数
console.log(date1);
//3.H5新增的 获取总的毫秒数
console.log(Date.now());
案例 倒计时
//倒计时效果
// 1.核心算法:输入的时间减去现在的时间就是剩余时间,即倒计时,但是不能拿着分秒相减,比如05分减去25分,结果会是负数。
// 2.用时间戳来做。用户输入的时间总的毫秒数减去,得到的就是剩余时间的毫秒数。
// 3.把剩余时间总的毫秒数转换为天、时、分、秒(时间戳转换时分秒)
// 转换公式如下:
// d = parseInt(总秒数/60/60/24); //计算天数
// h = parseInt(总秒数/60/60%24); //计算小时
// m = parseInt(总秒数 /60 %60); //计算分数
// s = parseInt(总秒数%60); //计算当前秒数
function countDown(time) {
var nowTime = +new Date(); //返回当前时间总的毫秒数
var inputTime = +new Date(time); //返回的是用户输入时间总的毫秒数
var times = (inputTime - nowTime) / 1000; //times是剩余时间总的毫秒数 1秒等于1000毫秒
var d = parseInt(times / 60 / 60 / 24); //天
d = d < 10 ? ‘0’ + d : d; //小于10补0
var h = parseInt(times / 60 / 60 % 24); //时
h = h < 10 ? ‘0’ + h : h;
var m = parseInt(times / 60 % 60); //分
m = m < 10 ? ‘0’ + m : m;
var s = parseInt(times % 60); //当前的秒数
s = s < 10 ? ‘0’ + s : s;
return d + ‘天’ + h + ‘时’ + m + ‘分’ + s + ‘秒’;
}
console.log(countDown(‘2021-12-21 12:00:00’));
var date = new Date();
console.log(date);
5.1数组对象的创建
创建数组对象的两种方式:
字面量方式
new Array()
//创建数组的两种方式:
//1.利用数组字面量
var arr = [1,2,3];
console.log(arr);
console.log(arr[0]);
//2.利用new Array()
var arr1 = new Array(); //创建了一个空的数组
// var arr1 = new Array(2); //这个2 表示数组长度为2 里面有2个空的数组元素
var arr1 = new Array(2,3); //等价于[2,3]这样写表示 里面有2个数组元素 是2和3 必须两个以上才能写进去值
console.log(arr1);
检测是否为数组两种方式:
(1)instanceof 运算符 它用来检测是否为数组
(2)Array.isArray()

5.3添加删数组元素的方法
方法名 | 说明 | 返回值
push(参数1…) | 末尾添加一个或多个元素,注意修改原数组 | 并返回新的长度
pop() | 删除数组最后一个元素,把数组长度减1无参数、修改原数组 | 返回他删除的元素的值
unshift(参数1…) | 向数组的开头添加一个或更多元素,注意修改原数组 | 并返回新的长度
shift() | 删除数组的第一个元素,数组长度减1无参数、修改原数组 | 并返回第一个元素的值
添加元素
//添加删除数组元素方法
//1.push() 在我们数组的末尾 添加一个或者多个数组元素 push 推
var arr = [1,2,3];
arr.push(4,5);
console.log(arr);
//(1)push 是可以给数组追加新的元素
//(2)push() 参数直接写 数组元素就可以了
//(3)push 完毕之后,返回的结果是 新数组的长度
//(4)原数组也会发生变化
//2.unshift 在我们数组的开头 添加一个或者多个数组元素
var arr1 = [2,3,4,5];
arr1.unshift('pink',1);
console.log(arr1);
//(1)unshift 是可以给数组前面追加新的元素
//(2)unshift 参数直接写 数组元素就可以了
//(3)unshift 完毕之后,返回的结果是 新数组的长度
//(4)原数组也会发生变化
删除元素
//3.pop() 它可以删除数组的最后一个元素
var arr = [1,2,3,4,5];
arr.pop();
console.log(arr);
//(1)pop() 是可以删除数组最后一个元素 记住只能一次删除一个元素
//(2)pop() 里面不用写参数
//(3)pop完毕之后,返回的结果是删除的那个元素
//(4)原数组也会发生变化
//4.shift() 它可以删除数组的第一个元素
console.log(arr.shift());
//(1)shift() 是可以删除数组第一个元素 记住只能一次删除一个元素
//(2)shift() 里面不用写参数
//(3)shift完毕之后,返回的结果是删除的那个元素
//(4)原数组也会发生变化
案例 筛选数组
//有一个包含工资的数[1500,1200,2000,2100,1800]要求把数组中的工资超过2000删掉 小于两千放到新数组
var arr = [1500,1200,2000,2100,1800];
var newArr = [];
for(var i = 0;i < arr.length;i++){
if (arr[i] < 2000){
// newArr[newArr.length]= arr[i];
newArr.push(arr[i])
}
}
console.log(newArr);
5.4数组排序
方法名 | 说明 | 是否修改原数组
reverse() | 颠倒数组中元素的顺序,无参数 | 该方法会改变原来的数组 返回新数组
sort() | 对数组的元素进行排序 | 该方法会改变原来的数组 返回新数组
//数组排序
//1.翻转数组
var arr = [‘pink’,‘red’,‘blue’];
arr.reverse();
console.log(arr);
//2.数组排序(冒泡排序)
var arr1 = [3,4,7,1];
arr1.sort(function(a,b){
return a-b; //升序的顺序排列
return b-a; //降序的顺序排列
});
console.log(arr1)
5.5数组索引方法
方法名 | 说明 | 返回值
indexOf() | 数组中查找给定元素的第一个索引 | 如果存在返回所有索引号
lastlndexOf() | 在数组中的最后一个的索引, | 如果存在的返回索引号 如果不存在 则返回-1
//返回数组元素索引号方法 indexOf(数组元素) 作用就是返回该数组元素的索引号 从前面开始查找
//如果数组中有两个相同的值 他只返回第一个满足条件的索引号
//他如果在数组中找不到该元素,则返回-1
var arr = [ ‘red’ , ‘green’ , ‘blue’ , ‘pink’];
console.log(arr.indexOf(‘blue’)); //2
// 返回数组元素索引号方法 lastIndexOf(数组元素) 作用就是返回该数组元素的索引号 从后面开始查找
console.log(arr.lastIndexOf(‘blue’)); //4
案例 数组去重
//数组去重[‘c’,‘a’,‘z’,‘a’,‘x’,‘a’,‘x’,‘c’,‘b’]要求去除数组中重复的元素。
// 1.目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重
// 2.核心算法:我们追历旧数组,然后拿者旧数组元素去查询新数组,如果该元素在新数组里面没有出现我们就添加,否则不添加。
// 3.我们怎么知道该元素没有存在?利用 新数组,indexof(数组元素)如果返回时 -1就说明 新数组里面有改元素
// 封装一个 去重的函数数 unique 独一无二的
function unique(arr) {
var newArr = [];
for(var i = 0;i < arr.length;i++){
if(newArr.indexOf(arr[i])=== -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
var demo = unique(['c','a','z','a','x','a','x','c','b'])
console.log(demo);
5.6数组转换为字符串
方法名 | 说明 | 返回值
toString() | 把数组转换成字符串,逗号分隔每一项 | 返回一个字符串
join(‘分隔符’) | 方法用于把数据中所有元素转换成一个字符串 | 返回一个字符串
// 数组转换为字符串
//1.toString() 将我们的数据转换为字符串
var arr = [1,2,3];
console.log(arr.toString()); //1,2,3
//2.join(分隔符)
var arr1 = [‘green’,‘blue’,‘pink’];
console.log(arr1.join()); //green,blue,pink
console.log(arr1.join(’|’)); //green|blue|pink
方法名 | 说明 | 返回值
concat() | 连接两个或多个数组 不影响原数组 | 返回一个新的数组
slice() | 数组截取slice(beging,end) | 返回被截取项目的新数组
splice() | 数组删除splice(第几个开始的,要删除个数) | 返回已被删除的新数组
6.1基本包装类型
为了方便操作基本数据类型,javascript还提供了三个特殊的引用类型:String、Number和Boolean。
基本包装类型就是把简单的数据类型包装成复杂数据类型,这样的基本数据类型就有了属性和方法
//基本包装类型
var str = ‘andy’;
console.log(str.length);
//对象 才有 属性和方法 复杂数据类型才有 属性和方法
//简单数据类型怎么会有length 属性呢?
//基本包装类型: 就是把简单数据类型 包装成为了 复杂数据类型
//(1)吧简单数据类型包装成复杂数据类型
var temp = new String(‘andy’);
//(2) 把临时变量的值 给 str
str = temp;
// (2)销毁这个临时变量
temp = null;
6.2字符串的不可变
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中中开辟了一个内存空间。
//字符串的不可变
var str = ‘andy’;
console.log(str);
str = ‘red’;
console.log(str);
//因为我们字符串的不可变所以不要大量的拼接字符串
var str = ‘’;
for (var i = 1;i <= 100000;i++){
str+=i;
}
console.log(str);
6.3根据字符返回位置
字符串所有的方法,都不会修改字符本身(字符串是不可变的),操作完成会返回一个新的字符串。
方法名 | 说明
indexOf(‘要查找的字符,开始的位置’) | 返回并指定内容在原字符串中的位置,如果找不到就返回-1,开始的位置就是index索引号
lastindexOf() | 从后往前找,只找第一个匹配的
//字符串对象 根据字符返回位置 str。indexOf(‘要查找的字符’,[起始的位置])
var str = ‘改革春风吹满地,春天来了’;
console.log(str.indexOf(‘春’));
console.log(str.indexOf(‘春’,3)); //从索引号是3的位置开始往后查找
案例-求某个字符出现的次数
//查找字符串"abcoefoxyozzopp”中所有o出现的位置以及次数
//核心算法:先查找第一个o出现的位置
//然后 只要indexof 返回的结果不是就继续往后查找
//因为indexof 只能查找到第一个,所以后面的查找,一定是当前素引加1,从而继续查找
var str = “abcoefoxyozzopp”;
var index = str.indexOf(‘o’);
var num = 0;
console.log(index);
while(index !== -1) {
console.log(index);
num
index = str.indexOf(‘o’,index + 1)
}
console.log(‘0出现的次数:’ + num);
var str = [‘red’,‘blue’,‘red’,‘green’,‘pink’,‘red’];
var index = str.indexOf(‘red’);
console.log(index);
var num = 0;
while(index !== -1) {
console.log(index);
num++;
index = str.indexOf(‘red’,index + 1);
}
console.log('red出现的次数'+num);
6.4根据位置返回字符(重点)
方法名你 | 说明 | 使用
charAt(index) | 返回指定位置的字符(index字符串的索引号) | str.charArr(0)
charCodeAt(index) | 获取指定位置处字符的ASCII码(index索引号) | str.charcodeAt(0)
str[index] | 获取指定位置处字符 | HTML5,IE8+支持 和charAt()等效
//根据位置返回字符
//1.charAt(index) 根据位置返回字符
var str = ‘andy’;
console.log(str.charAt(3));
//遍历所有字符’
for(var i = 0;i
}
//2.charCodeAt(index) 返回相应索引号的字符ASCII值 目的:判断用户按下哪个键
console.log(str.charCodeAt(0));
//3.str[index] H5新增的
console.log(str[0]);
//有一个对象 来判断是否有该属性 对象[‘属性名’]
var str = {
age:18
}
if(str[‘age’]){
console.log(‘里面有age这个属性’);
} else {
console.log(‘里面没有age属性’);
}
var str = 'abcoefoxyozzopp';
var o = {};
for(var i = 0;i < str.length;i++){
var chars = str.charAt(i) // chars 是 字符串的每一个字符
if(o[chars]) { //o[chars]得到的是属性值
o[chars]++;
}else{
o[chars] = 1;
}
}
console.log(o);
//2.遍历对象
var max = 0;
var ch = '';
for(var k in o){
// k 得到的是 属性名
// o[k] 得到的是属性值
if(o[k] > max){
max = o[k];
ch = k;
}
}
console.log(max);
console.log('最多的字符是'+ ch);
字符串操作方法(重点)
方法名 | 说明
concat(str1,st2,st3…) | concat()方法用于连接两个或者多个字符串。拼接字符串,等效于+,+更常用
substr(start,length) | 从start位置开始(索引号),length取的个数 重点记住这个
slice(start,end) | 从start位置开始,截取到end位置,end娶不到(他们俩都是索引号)
substring(start,end) | 从start位置开始,截取到end位置,end取不到 基本和slice相同 但是不接受负值
//字符串操作和方法
//1.concat(‘字符串1,字符串2’…)
var str = ‘andy’;
console.log(
str.concat(‘red’)
);
//2.substr('街区的起始位置','截取几个字符')
var str1 = '改革春风吹满地';
console.log(str1.substr(2,2)); //第一个2是索引号2 从第几个开始 第二个2是取几个字符
//3.替换字符 replace('被替换的字符','替换为的字符') 他只会替换第一个字符
var str1 = 'andyandy';
console.log(str1.replace('a','b'));
//有一个字符串'abcoefoxyozzopp'要求把里面的vo替换为*
var str2 = 'abcoefoxyozzopp';
while(str2.indexOf('o') !== -1){
str2=str2.replace('o','*');
}
console.log(str2);
//4.字符转换数组 split('分隔符') 前面我们学过join 把数组转换为字符串
var str3 = 'red,pink,blue';
console.log(str3.split(','));
var str4 = 'red&pink&blue';
console.log(str4.split('&'));
1.简单数据类型和复杂数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此又叫值类型string,number,boolean,undefined,null
//简单数据类型 null 返回的是一个空的对象 Object
var timer = null;
console.log(typeof timer);
//如果有个变量我们以后打算存储为对象,暂时没想好放什么,这个时候就给null
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
2.堆和栈
堆栈空间分配区别:
栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
简单数据类型存放到栈里面
2.栈(操作系统):存储复杂数据类型(对象),一般由程序员分配释放。若程序员不释放,由垃圾回收机制回收。
复杂数据类型存放到堆里面

注意:JavaScript中没有堆栈的概念,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式,便于将来学习其他语言
3.简单数据类型的内存分配
值类型(简单数据类型):string,number,boolean,undefind,null
值类型变量的数据直接存放在变量(栈空间)中



//1.简单数据类型是 存放到栈里面 里面直接开辟一个空间存放的是值
//2.复杂数据类型 首先在栈里面存放地址 16进制表示 然后这个地址指向堆里面的数据
5.简单类型传参
函数的形参可以看作是一个变量,当我们把一个值类型变量作为参数传递函数的形参时,其实是把变量在栈空间的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量

6.复杂数据类型
函数的形参也可以看作是一个变量,当我们把引用类型变量传递给形参时,其实是把变量在栈空间里面保存的堆地址赋值给了形参,形参和实参其实保存了同一个堆地址,所以操作的是同一个对象。


Web APls 和 JS 基础关联性
1.1JS组成

1.2 JS基础阶段以及web APls阶段
JS基础阶段
我们学习的是ECMASCRIPT标准规定的基本语法
要求掌握JS基本语法
只学习基本语法做不了常用的网页交互效果
目的是为了JS后面的课程打基础、做铺垫
Web APls阶段
web APIs是W3C组织的标准
Web APls 主要学习BOM 和 DoM
web Apls是我们JS所独有的部分
我们主要学习网页交互功能
需要使用js基础的内容做铺垫
JS基础学习 ECMAScript基础语法为后面做铺垫, Web APls是JS的应用,大量使用JS基础语法做交互效果
2.1API
API(应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而有无需访问源码,或理解内部工作机制的细节。
简单理解:API是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能
2.2Web API
Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)
现阶段针对浏览器讲解常用的API,主要针对浏览器做交互效果
MDN详细API:https://developer.mozilla.org/zh-CN/docs/Web/API
因为Web API很多,所以我们将这个阶段称为web APIs
2.3API和Web API总结
1.API是为我们程序员提供的一个接口,帮助我们实现某种功能,我们会使用就可以了,不必纠结内部如何实现
2.Web API主要是针对于浏览器提供的接口,主要针对于浏览器做交互效果
3.Web API一般都有输入和输出(函数的传参和返回值),Web API很多都是方法(函数)
4.学习Web API可以结合前面学习内置对象的思路学习(首先知道API是做什么的 再看下需不需要参数 第三个看看返回值是什么 最后代码验证一下)
1.1什么是DOM
文档对象模型(Document ObjectModel,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTTML或者XML)的标准编程接口
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式。
1.2 DOM树

文档:一个页面就是一个文档,DOM中使用document表示
标签:页面中的所有标签都是元素,DOM中使用element表示
节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上内容都看作是对象
2.1如果获取页面元素
DOM在我们实际开发中主要用来操作元素。
我们如何来获取页面中的元素呢?
获取页面中的元素可以使用以下几种方式:
根据id获取
根据标签名来获取
通过HTML5新增的方法获取
特殊元素获取
2.2根据id获取
使用 getElementByld()方法可以获取带有id元素的对象。
2.获取元素
2.3根据标签名获取
使用getElementsByTagName()方法可以返回带有指定标签名的对象的集合。nv
document.getElementsByTagName(‘标签名’)
注意:父元素必须是单个对象(必须指明是哪一个元素对象)获取的时候不包括父元素自己。
注意
1.因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历。
2.得到元素对象是动态的
2.4通过HTML5新增的方法获取
1.document.getElementsByClassName(‘类名’); //根据类名返回元素对象集合
2.document.querySelector(‘选择器’); //跟胡指定选择器返回第一个元素对象 必须加符号.就是类 #是id 标签不需要加符号
3.document.querySelectorAll(‘选择器’); //根据指定选择器返回
2.5获取特殊元素(body,html)
获取body元素
1.document.body //返回body元素对象
获取HTML元素
1.document.documentElement //返回HTML元素对象
3.事件基础
3.1事件概述
JavaScript使我们有能力创建动态页面,而事件是可以被Javascript侦测到的行为。
简单理解:触发—相应机制
网页中的每个元素都可以产生某些可以触发JavaScript的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作.
3.2执行时间的步骤
1.获取事件源
2.注册事件(绑定事件)
3.添加事件处理程序(采取函数赋值形式)
3.3常见的鼠标事件
鼠标事件 | 触发条件
onclick | 鼠标点击左键触发
onmouseover | 鼠标经过触发
onmouseout | 鼠标离开触发
onfocus | 获得鼠标焦点触发
onblur | 失去鼠标焦点触发
onmousemove | 鼠标移动触发
onmouseup | 鼠标弹起触发
onmousedown | 鼠标按下触发
JavaScript的DOM操作还可以改变网页内容、结构和样式,我们可以利用DOM操作元素改变元素里面的内容、属性等。注意以下都是属性
4.1改变元素内容
element.innerText
起始位置到终止位置的内容,但它抹去html标签,同时空格和换行也会抹去
element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
123
innerText 和 innerHTML 区别
我是文字 123
4.2常用元素的属性操作
1.innerText、innerHTML 改变元素内容
2.src、href
3.id、alt、title
案例
4.3表单元素的属性操作
利用DOM可以操作如下表单元素的属性:
type、value、checked、selected、disabled
4.4样式属性操作
我们可以通过js修改元素的大小、颜色、位置等样式。
1.element.styly 行内样式操作
2.element.className 类名样式操作
注意:
1.JS里面的样式采取驼峰命名法 比如 fontsize、 backgroundColor
2.JS修改 style 样式操作,产生的是行内样式,CSS权重比较高
3.如果样式修改比较多,可以采取操作类名的方式更改元素样式
4.class因为是个保留字,因此使用className来操作元素类名属性
5.className 会直接更改元素的类名,会覆盖原先的类名
操作元素总结
操作元素是DOM核心内容

4.5排他思想

如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法:
1.所有元素全部清除样式(干掉其他人)
2.给当前元素设置样式(留下我自己)
3.注意顺序不能颠倒,首先干掉其他人,再设置自己
4.6自定义属性的操作
1.获取属性值
element.属性 获取属性值.
element.getAttribute(‘属性’);
区别:
element.属性 获取属性值(元素本身自带的属性)
element.getAttribute(‘属性’);主要获得自定义的属性(标准)我们程序员自定义的属性
2.设置属性值
element.属性=‘值’ 设置内置属性值
elementsetAttribute(‘属性’,‘值’);
区别:
element.属性 设置内置属性值
element.setAttibute(‘属性’);主要设hi自定义属性(标准)
3.移除属性
element.removeAttribute(‘属性’);
4.7 H5自定义属性
自定义属性的目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
自定义属性获取是通过getAttribute(‘属性’)来获取。
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
H5给我们新增了自定义属性:
1.设置H5自定义属性
H5规定自定义属性data-开头做为属性名并且赋值。
比如
5.1为什么学习节点操作
获取元素通常使用两种方式:
1.利用DOM提供的方法获取元素
document.getElementById()
document.getElementsByTagName()
document.querySelector等
非常繁琐 逻辑性不强
2.利用节点层级关系获取元素
利用父子兄节点关系获取元素
逻辑性强 但是兼容性较差
5.2节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等)在DOM中,节点使用node来表示。
HTML DOM树中的所有节点均可通过javascript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。

一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
元素节点 nodeType为1
属性节点nodeType为2
文本节点nodeType为3(文本节点包含文字、空格、换行等)
我们在实际开发中 节点操作主要操作的是元素节点
5.3 节点层级
利用DOM树可以把节点划分成为不同的层级关系,常见的是父子兄级关系。
1.父级节点
node.parentNode
parentNode属性可返回某节点的父节点,注意是最近的一个父节点
如果指定的节点没有父节点则返回null
2.parentNode.children (非标准)
parentNode.children是一个只读属性,返回所有的子元素节点。他只返回子元素节点,其余节点不返回(这个是我们重点掌握的)。
虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
//DOM 提供的方法(API)获取
var ul = document.querySelector(‘ul’);
//2.children 获取所有的子元素节点 也是我们实际开发常用的
console.log(ul.children);
3.parentNode.firstChild 获取子元素第一个子节点
firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点
4.parentNode.lastchild 获取子元素最后一个子节点
lastChild返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点
5.parentNode.firstElementChild
firstElementChild 第一个子元素节点,找不到则返回null
6.parentNode.lastElementChild
lastElementChild返回最后一个子元素节点,找不到则返回null
注意:这两个有兼容性的问题
实际开发中,firstChild和lastChild包含其他节点,操作不方便,而firstElementChild和lastElementChild又有兼容性问题。
解决方案:
1.如果想要第一个子元素节点,可以使用parentNode.chilren[0]
var ol = document.querySelector(‘ol’);
// 1.firstChild 第一个子节点 不管是文本节点还是元素节点
console.log(ol.firstChild);
console.log(ol.lastChild);
// 2.firstElementChild 返回第一个子元素节点
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
// 3.实际开发的写法 既没有兼容性问题 又返回第一个子元素
console.log(ol.children[0]);
console.log(ol.children[3]);
console.log(ol.children[ol.children.length-1]);
3.兄弟节点
1.node.nextSibling
node.nextSibling返回当前元素下的一个兄弟节点,找不到则返回null。同样,也是包含所有的节点。
2.node.previousSibling
previousSibling 返回当前元素上一个兄弟节点,找不到则返回null。同样,也是包含所有的节点
3.node.nextElementSibling
nextElementSibling返回当前元素下一个兄弟元素节点,找不到则返回null
4.node.previousElementSibling
previousElementSibling返回当前元素上一个兄弟节点,找不到则返回null
注意:这两个方法有兼容性问题 iE9以上支持
怎么解决? 封装函数
function getNextElementSibling(element){
var el = element;
while(el = el.nextSibling) {
if (el.nodeType === 1) {
return el;
}
}
return null;
}
var div = document.querySelector(‘div’);
// 1.nextSibling 下一个兄弟节点 包含元素节点或者文本节点等等
console.log(div.nextSibling);
console.log(div.previousSibling);
// 2.nextElementSibling得到下一个兄弟元素节点
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
5.4 创建节点
document.createElement(‘tagName’)
document.createElement()方法创建由tagName指定的HTML元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
5.4添加节点
1.node.appendChild(child)
node.appendChild()方法将一个节点添加到指定父节点的子节点列表末尾。类似于css里面的after伪元素
2.node.insertBefore(child,指定元素)
node.insertBefore()方法将一个节点添加到父节点的指定子节点前面。类似于CSS里面的before伪元素
//1.创建节点元素节点
var li = document.createElement(‘li’);
//2.添加节点 node.appendChild() node是父级 Child子级 后面追加元素
var ul = document.querySelector(‘ul’);
ul.appendChild(li);
//3.添加节点 node.insertBefore(child,指定元素)
var lili = document.createElement(‘li’);
ul.insertBefore(lili, ul.children[0]);
// 4.我们想要在页面添加新的元素:1.创建元素 2.添加元素
5.5删除节点
node.removeChild(child)
node.removeChild()方法从DOM中删除一个子节点,返回删除的节点。
删除
5.6 复制节点(克隆节点)
node.cloneNode()
node.cloneNode() 方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点
注意:
1.如果括号参数为空或者为false,则是浅拷贝,即克隆复制节点本身,不克隆里面的子节点。
/2.node.cloneNode(true);括号为true 深拷贝 复制标签复制里面的内容
5.8 三种动态创建元素区别
document.write()
element.innerHTML
document.createElement()
区别:
1.document.write是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致整个页面全部重绘
2.innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘
3.innerHTML创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
4.createElement()创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML采取数组形式拼接 效率要比createElement高
6.DOM重点核心
文档对象模型 简称DOM 是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
W3C已经定义了一系列的DOM接口,通过这些接口可以改变网页的内容结构和样式。
1.对于javascript,为了能够使javascript操作HTML,javascript就有了一套自己的dom编程接口
2.对于HTML,dom使得html形成一棵dom树,包含 文档、元素、节点
关于DOM操作 我们主要针对于元素的创建 主要有增、删、改、查、属性操作、事件操作
6.1 创建
1.document.write
2.innerHTML
3.createElement
6.2 增
1.appendChild
2.insertBefore
6.3 删
1.removeChild
6.4 改
主要修改dom的元素属性,dom元素的内容、属性,表单的值等
1.修改元素属性:src、href、title等
2.修改普通元素内容:value、type、disable等
3.修改表单元素:value、type、disabled等
4.修改元素样式:style、className
6.5 查
主要获取dom查询元素
1.DOM提供的API方法:getElementById、getElementsByTagName古老用法不太推荐
2.H5提供的新方法:querySelector、querySelectorAll 提倡
3.利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling)提倡
6.6 属性操作
主要针对于自定义属性。
1.setAttribute:设置dom的属性值
2.getAttribute:得到dom的属性值
3.removeAttribute移除属性
6.7事件操作
给元素注册事件,采取 事件源.事件类型=事件处理程序

1.1 注册事件概述
给元素添加事件,称为注册事件或者绑定事件。
注册事件有两种方式:传统方式和方法监听注册方式
传统注册方式
利用on开头的事件onclick
1.3 attachEvent 事件监听方式
eventTarget.attachEvent(eventNameWithOn,callback)
eventTarget.attachEvent()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,指定的调回函数就会被执行。
该方法接收两个参数:
eventNameWithOn:事件类型字符串,比如onclick、onmouseover,这里要带on
callback:事件处理函数,当目标触发事件时调用函数被调用
注意:IE8及早期版本支持
//3.attachEvent ie9以前的版本支持
btns[2].attachEvent(‘onclick’,function(){
alert(11);
})
2.1 删除事件的方式
1.传统注册方式
evenTarget.onclick = null;
2.方法监听注册方式
evenTarget.removeEventListener(type,listener[,useCapture]);
eventTarget.detachEvent(eventNameWithon,callback);
2.2删除时间兼容性解决方案

事件流描述的是从页面中接收事件的顺序。
事件发生时在元素节点直接按照特定的顺序传播,这个传播过程即DOM事件流。
比如我们给div注册了点击事件

DOM事件流分为3个阶段:
1.捕获阶段
2.当前目标阶段
3.冒泡阶段
事件冒泡:IE最早提出,事件开始时由最具体的元素接受,然后逐级向上传播到DOM最顶层节点的过程。
事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程
理解:我们向水中扔一块石头,首先它会有一个下降过程,这个过程就可以理解为最顶层向事件发生的最具体元素(目标点)的捕获过程;之后产生泡泡,会在最低点(看具体元素)之后漂浮在水面上,这个过程相当于事件冒泡。

注意
1.JS代码中之能执行捕获或者冒泡其中的一个阶段
2.onclick和attachEvent只能得到冒泡阶段
3.addEventListener(type,listener[,useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。
4.实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
5.有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
6.事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件。
//dom事件流 三个阶段
//1.JS代码中只能执行捕获或者冒泡其中的一个阶段
//2.onclick 和 attachEvent(ie)只能得到冒泡阶段
//3.捕获阶段 如果addEventListener 第三个参数是 true 那么处于捕获阶段 document-> html -> body -> father -> son
var son = document.querySelector(’.son’);
son.addEventListener(‘click’,function(){
alert(‘son’);
},true);
var father = document.querySelector(’.father’);
father.addEventListener(‘click’,function(){
alert(‘father’);
},true);
//4.冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段 son-> father-> body-> html-> document
var son = document.querySelector(’.son’);
son.addEventListener(‘click’,function(){
alert(‘son’);
},false);
var father = document.querySelector(’.father’);
father.addEventListener(‘click’,function(){
alert(‘father’);
},false);
document.addEventListener(‘click’,function(){
alert(‘document’)
})
4.1 什么是事件对象
eventTarget.onclick = function(event){}
eventTarget.addEventListener(‘click’,functon(event))
//这个event就是事件对象,我们还喜欢的写成e或者evt
官方解释:event对象代表事件的状态,比如键盘按键的状态、鼠标位置、鼠标按钮的状态。
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都会放到这个对象里面,这个对象就是事件对象event,他有很多属性和方法。
比如:
谁绑定了这个事件
鼠标触发事件后,会得到鼠标的相关信息,比如鼠标位置
键盘事件的话,会得到键盘的相关信息,如按了哪个键
4.2 事件对象的使用语法
这个event是个形参,系统帮我们设为事件对象,不需要传递实参过去。当我们注册事件时,event对象都会被系统自动创建,并依次传递事件监听器(事件处理程序)
4.3 事件对象的兼容性方案
事件对象本身获取存在兼容问题:
标准浏览器是浏览器给方法传递的参数,只需要定义形参e就可以获取到。
在ie678中,浏览器不会给方法传递参数,如果有需要的话,需要到window.event中查找
解决:
e = e ||window.event;
4.4 事件对象的常见属性和方法
事件对象属性方法 | 说明
e.target | 返回触发事件的对象 标准
e.srcElement | 返回触发时间的对象 非标准 ie678使用
e.type | 返回事件的类型 比如click mouseover 不带on
e.cancelBubble | 该属性组织 组织冒泡 非标准 ie678使用
e.returnValue | 该属性 阻止默认事件 (默认行为) 非标准 ie678使用 比如不让链接直接跳转
e.preventDefault() | 该方法 组织默认事件 (默认行为)标准 比如不让链接跳转
e.stopPropagation() | 组织冒泡 标准
//常见事件对象的属性和方法 e.target和this区别
//1.e.target 返回的是触发时间的对象(元素)this返回的是绑定事件的对象(元素)
//区别:e.target 点击了那个元素,返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁
var div = document.querySelector(‘div’);
div.addEventListener(‘click’, function (e) {
console.log(e.target);
console.log(this);
})
var ul = document.querySelector(‘ul’);
ul.addEventListener(‘click’, function (e) {
//我们给ul绑定了事件 那么this 就指向ul
console.log(this);
console.log(e.currentTarget);
// e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li
console.log(e.target);
})
//了解兼容性
// div.onclick = function () {
// e = e || window.event;
// var target = e.target || e.srcElement;
// console.log(target);
// }
// 2.了解 跟 this 有个非常相似的属性 currentTarget ie678不认识
事件对象组织默认行为
5.1阻止事件冒泡的两种方式
事件冒泡:开始时由最具体的元素接受,然后逐级向上传播得到DOM最顶层节点。
事件冒泡本身特性,会带来的坏处,也会会带来好处,需要我们灵活掌握。
组织事件冒泡
标准写法:利用事件对象里面的stopPropagation()方法 ‘stop停止 Propagation传播’
e.stopPropagation() 常用
非标准写法:IE6-8利用事件对象 cancelBubble属性
5.2组织冒泡的兼容性解决方案
if(e && e.stopPropagation){
e.stopPropagation();
} else {
windwo.event.cancelBubble = ture;
}

事件冒泡本身的特性,会带来的坏处,也会带来好处,需要我们灵活掌握,生活中有如下场景:
咱们班有100个同学,快递员有100个快递,如果一个个送花费时间较长。同时每个同学领取的时候,也需要排队领取,也得花费时间较长,何如?
解决方案:快递员把100个快递,委托给班主任,班主任把这些快递放到办公室,同学们下课自行领取即可。
优势:快递员省事,委托给班主任就走了。同学们领取也方便,因为相信班主任。
事件委托
事件委托也称为事件处理,在jQuery里面称为事件委派
事件委托的原理
不要给每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
以上案例:给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,时间会冒泡到ul上,ul有注册事件,就会触发事件监听器
事件委托的作用
我们只操作了一次DOM,提高了程序的性能。
7.1常见的鼠标事件
鼠标事件 | 触发事件
onclick | 鼠标点击左键触发
onmouseover | 鼠标经过触发
onmouseout | 鼠标离开触发
onfocus | 获得鼠标焦点出发
onblur | 失去鼠标焦点触发
onmouseove | 鼠标移动触发
onmouseup | 鼠标弹起触发
onmousedown | 鼠标按下触发
1.禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
document.addEventListener(‘contextmenu’,function(e){
e.preventDefault();
})
2.禁止鼠标选中(selectstart开始选中)
document。addEventListener(‘selectstart’,function(e){
e.preventDefault();
})
7.2 鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象MouseEvent和键盘事件对象KeyboardEvent。
鼠标事件对象 | 说明
e.clientX | 返回鼠标相对于浏览器可视窗口的x坐标
e.clientY | 返回鼠标相对于浏览器可视区的Y坐标
e.pageX | 返回鼠标相对于文档页面的X坐标 ie9+支持
e.pageY | 返回鼠标相对于文档页面的Y坐标 IE9+支持
e.screenX | 返回鼠标相对于电脑屏幕的X坐标
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标
//鼠标事件对象 MouseEvent
document.addEventListener(‘click’,function(e){
//1.client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log(’-------------------------------’);
//2.page 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
})
8.1 常用键盘事件
事件除了使用鼠标触发,还可以使用键盘触发。
键盘事件 | 触发事件
onkeyup | 某个键盘按键松开时触发
onkeydown | 某个键盘按键被按下时触发
onkeypress | 某个键盘按键被按下时触发 但是它不识别功能键 比如 ctrl shift 箭头等
注意:
1.如果使用addEventListener不需要加on
2.onkeypress和前面2个的区别是,他不识别功能键,比如左右箭头,shift等
3.三个事件的执行顺序是:keydown–kepress–keyup