4.变量
4.1变量的概述
变量就是一个装东西的盒子。
通俗来说,变量就是用于存储数据的容器,我们通过变量名(一段内存的别名)获取、修改数据。
本质上,变量是程序在内存中申请的一块用来存放数据的空间。
注:
JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。释放的过程称为垃圾回收。
疑问:
是声明未赋值也分配内存了吧?因为未赋值,值是undefined
4.2变量的使用
步骤:
1.声明变量(ES5只有两种方式声明变量: var 和 function,函数也可以当做是变量)
// 声明一个名词为age的变量
var age;
- var是一个JS关键字,用来声明变量(variable是变量的意思)。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管。
- age是程序员定义的变量名,我们要通过变量名访问。
2.赋值
age = 10;
- = 在这里是赋值的意思
- 变量值是程序员保存到变量空间里的值
变量的初始化:
var age = 10;
4.3变量语法扩展
4.3.1更新变量
一个var关键字声明的变量被重新赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。
4.3.2同时声明多个变量,用逗号隔开
var age = 18,
address = '火影村',
salary = 2000;
4.3.3var声明变量的特殊情况
- 只声明不赋值,结果是undefined
- 不声明不赋值直接使用某个变量,会报错
- 不声明直接赋值并使用,可以输出但不提倡,会变成全局变量即全局对象的属性(因为无论这个变量是在哪个作用域内直接赋值的,它都没声明则会一直沿着作用域链往上找,直到全局作用域都找不到,在非严格模式的情况下,就会直接在全局对象身上声明这个属性)
4.4变量命名规范
- 由字母、数字、下划线、美元符号组成
- 严格区分大小写
- 不能以数字开头
- 不能是关键字、保留字
注意: 尽量不要用name这个单词作为变量名,因为在浏览器模式下,window这个顶级对象有一个叫name的属性。
5.数据类型
5.1数据类型简介
因为不同的数据所需要占用的存储空间是不同的,因此为了便于把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型。
在JS中,变量的数据类型是不确定的(弱类型语言),在程序运行过程中根据等号右边的值才可以确定。
var num; // 不确定数据类型
var num = 10; // 确定了数据类型
注意:
- 因为JavaScript是弱类型、动态类型,意味着相同的变量可以用作不同的类型
- 编程语言可以分为 强/弱类型、静态/动态类型(在编译阶段/运行阶段进行类型检查)
var x = 6; // x为数字
x = 'Bill'; // x为字符串
5.2简单数据类型(值/基本数据类型,es5有5种)
5.2.1数字型进制
二进制、八进制、十进制、十六进制
八进制(数字前面加0表示八进制):0~7 // 010 相当于十进制里面的8
十六进制(数字前面加0x表示十六进制):0~9 a~f // 0xa相当于十进制中的10
二进制待展开…
5.2.2数字型范围
JS中数值有最大值和最小值
console.log(Number.MAX_VALUE);
console.log(Number.MIN_VALUE);
5.2.3数字型三个特殊值
console.log(Number.MAX_VALUE * 2);// Infinity无穷大
console.log(Number.MIN_VALUE * 2); // -Infinity无穷小
console.log('pink' - 100); // NaN非数字
5.2.4数字型Number
isNaN(xxx)
//用来判断是否为非数字并且返回一个布尔值,如果是false则是数字,true则为非数字
Number.isNaN(xxx)
区别:
isNaN方法首先转换类型,而Number.isNaN方法首先判断传入的参数是否为数值类型,只要是非数值类型就直接返回false,
isNaN不能用来判断是否严格等于NaN,Number.isNaN方法可用
如:
isNaN(‘123’) // true
注意:
typeof(NaN) // Number
isNaN(NaN) // true
5.2.5字符串型String
可以是单引号也可以是双引号,只要加了引号都是字符串,如:'10’也是字符串型。
引号有嵌套,就近原则(外双内单或外单内双)。
5.2.6字符串转义符
都是以\开头,要写到引号里
\n
换行 转义符 -> 告诉 系统 要进行 换行了\\
斜杠 转义符 -> 告诉 系统 第二个 \ 不是转义符,而是 字符串\r
换行\t
tab 退格键\'
告诉浏览器 ’ 是一个 普通的字符串,不要当做 字符串的 开始或结束 字符\"
告诉浏览器 " 是一个 普通的字符串,不要当做 字符串的 开始或结束 字符
5.2.7字符串长度
字符串是由若干字符组成的,这些字符的数量就是字符串的长度。
通过字符串的length属性可以获取整个字符串的长度。
var str='my name is andy';
console.log(str.length);
5.2.8字符串的拼接
多个字符串之间使用+号拼接 字符串+任意类型 = >字符串型
console.log('12'+12); // '1212'
console.log(12+12); // 24
数值相加,字符相连
var age = 18;
console.log('小野友树'+age+'岁');
//变量不要写到字符串里,而是通过和字符串相连的方式实现的
5.2.9显示年龄案例
var age = prompt('请输入您的年龄!'); //用户输入
var str = '您的年龄是' + age + '岁'; //程序内部处理
alert(str); //输出结果
5.2.10布尔型Boolean
true/false(1/0)
注意: 布尔型与数字型在相加时会转换为1/0再相加
console.log(true + 1) //2
5.2.11Undefined型和Null型
null 表示一个值被定义了,定义为“空值”; undefined 表示根本不存在定义。
-
undefined表示"缺少值",此处应该有值,但是没有定义
- 如果一个变量只声明未赋值,则为undefined
- 对象没有赋值的属性,该属性的值为undefined
- 调用函数时,应该提供的参数没有提供,该参数等于undefined(即实参小于形参个数)
- 函数必须有返回值,可以通过return设置;当没有写return语句时,默认返回undefined
- 没有数组下标的数组元素,输出的结果是undefined
- undefined与字符串相加 也是字符串
- undefined默认转成NaN,与数字或true(相当于1)相加 则为NaN
-
null表示"没有对象",是空对象的指针
- 作为对象原型链的终点
- 作为函数的参数,表示该函数的参数不是对象;在开发时,如果需要传递参数,且参数是对象,但是我们暂时不想传递或者不需要传递,可以传null ;
- Null与字符串相加还是字符串
- Null默认转成0,和数字(true/false)相加则为相加的数字如null+1 则为1
5.3获取数据类型typeof
var num = 10;
console.log(typeof num); //Number
var timer = null;
console.log(typeof timer); //Object
//根据f12控制台看颜色
注:获取数据类型的三种方式
- typeof
- instanceof
- Object.prototype.toString.call()
5.4字面量
字面量是在源代码中一个固定值的表示法,通俗来说,就是字面量表示如何表达这个值。
- 数字型字面量:8,9,10
- 字符串型字面量:‘小野友树’
- 布尔型字面量:true,false
- 数组
[]
- 函数
()
- 对象
{}
5.5数据类型转换
5.5.1什么是数据类型转换
一种数据类型的变量转换为另一种数据类型
5.5.2转换为字符串
- 变量.toString() 方法
var num= 1;
str = num.toString();
console.log(typeof str); //String
- String() 强制类型转换
var num= 1;
console.log(String(num));
- 加号拼接空字符串(常用,也称隐式转换)
var num= 1;
console.log(num + '');
5.5.3转换为数字型(重点)
- parseInt(string) 得到的是整数
var age = prompt('输入您的年龄');
console.log(age); //这时是字符串型的
console.log(parseInt(age)); //这时就是数字型的了
console.log(parseInt('3.9'));// 3 会取整
console.log(parseInt('120px'));// 120 会去掉单位
console.log(parseInt('rem120px'));// NaN
- parseFloat(变量/常量) 得到的是浮点数
var age = prompt('输入您的年龄');
console.log(age); //这时是字符型的
console.log(parseFloat(age)); //这时就是数字型的了
console.log(parseFloat('3.9'));// 3.9
console.log(parseFloat('120px'));// 120 会去掉单位
console.log(parseFloat('rem120px'));// NaN
- Number(变量/常量) 强制类型转换
var str = '123';
console.log(Number(str)); //123
- 利用算数运算 - * / 隐式转换
console.log('12' - 0); //12
console.log('123' - '120'); //3
5.5.4计算年龄案例
var year = prompt('请输入您出生的年份');
var age = 2021 - year; //prompt输入,year取过来的是字符串型 ,而此处是-是隐式转换
alert('您今年已经' + age + '岁啦!');
5.5.5简单加法器案例
var num1 = prompt('请输入第一个值!');
var num2 = prompt('请输入第二个值!');
var result = parseFloat(num1) + parseFloat(num2);//注意数据类型转换!
alert('计算结果为:' + result + '!');
5.5.6转换为布尔型
Boolean()强制类型转换
代表空、否定的值(如下)会被转换为false,其余的都会被转换为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
6.扩展阅读
6.1解释型语言和编译型语言
计算机不能直接理解任何除了机器语言以外的语言,所以必须要把程序员所写的程序语言翻译成机器语言才能执行程序。程序语言翻译成机器语言的工具,被称为翻译器。
翻译器翻译的方式有两种:编译、解释。区别在于翻译的时间点不同。
编译器是在代码执行之前进行编译,生成中间代码文件。
解释器是在运行时进行及时解释,并立即执行(当编译器以解释方式运行时,也称为解释器)。
6.2标识符、关键字、保留字
6.2.1标识符
是开发人员为变量、属性、函数、参数起的名字,不能是关键字或保留字
6.2.2关键字
指JS本身已经使用了的字,不能再用它们充当变量名、方法名
包括:break、delete、if、this、while、case、do、in、throw、with、catch、else、instanceof、try、continue、finally、new、typeof、for、return、default、function、switch、void等。
6.2.3保留字
实际上就是预留的“关键字”,虽然暂时不是关键字,但未来可能会成为
abstract、double、goto、native、static、boolean、enum、implements、package、super、byte、char、class、const、public等等。
7.运算符
也称操作符,是用于实现赋值、比较和执行算术运算等功能的实现
7.1算术运算符
7.1.1+ - * / %
注意:
在浮点数的算术运算里会有问题,不能直接拿着浮点数判断是否相等。0.1 + 0.2 === 0.3 ???
判断一个数能否被整除 用取余 %
7.1.2表达式和返回值
由数字、运算符、变量组成的式子是表达式,最终给我们的结果是返回值
7.2递增、递减运算符
num++(后置)、++num(前置)
num–、–num //与变量配合
7.3比较运算符
注意:返回值是布尔型
console.log(18 == '18'); //true == 默认转换数据类型 会把字符串的数据转换成数字型
console.log(18 === '18'); //false
7.4逻辑运算符
用于进行布尔值运算
注意*短路问题:当有多个表达式(值)时,左边的表达式可以确定结果时,就不再继续计算右边的表达式的值;
逻辑与
表达式1&&表达式2
如果第一个表达式的值为真,则返回第二个表达式的值
如果第一个表达式的值为假,则返回第一个表达式的值
数字除了0以外,其他数都是真
123&&456 //456
0&&123 //0
如果有空的或者否定的为假 其余为真
0 ‘’ null undefined NaN 为假
逻辑或
表达式1||表达式2
如果第一个表达式的值为真,则返回第一个表达式的值
如果第一个表达式的值为假,则返回第二个表达式的值
123||456 //123
123||456||789 //123
0||456||789 //456
7.5赋值运算符
= += -= *= /= %=
7.6运算符优先级
1. 小括号
()
2. 一元运算符
++ -- !
3. 算数运算符
加(+);减(-);乘(*);除(/);取于(%);这里是先乘(*)除(/)取于(%)后加(+)减(-)。
4. 关系运算符
大于(>);大于等于(>=);小于(<);小于等于(<=)。
5. 相等运算符
等于(==);不等于(!=);全等于(===);不全等于(!==)。
6. 逻辑运算符
先且(&&)后或(||)。
7. 赋值运算符(=)。
8. 逗号运算符(,)。
从高到低
8.流程控制
控制代码执行顺序:顺序、分支、循环
8.1顺序结构
最简单、最基本的流程控制,按顺序依次执行
8.2分支结构
根据不同的条件,执行不同的代码,得到不同的结果
8.2.1if语句及闰年案例
if(条件表达式) {
// 执行语句
}
if() {
} else {
}
闰年案例:
//能被4整除并且不能被100整除 或者 能被400整除
var year = prompt('请输入年份!');
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
alert(year + '是闰年!');
} else {
alert(year + '是平年!');
}
8.2.2多分支语句if else if
if(条件表达式1){
}else if(条件表达式2){
}else if(条件表达式3){
}else{
//最后的语句;
}
8.2.3三元运算符
条件表达式 ?表达式1 :表达式2 //真1假2
// 倒计时
var result = time < 10 ? '0' + time : time
8.2.4switch语句
针对特定值的选项
switch(表达式){
case value1:
执行语句1;
break;
case value2:
执行语句2;
break;
...
default: 执行最后的语句;
break;
}
注意:
- 开发中表达式常写成一个变量
- 要与case里的值全等 ===
- 从匹配的case一直执行到break
- switch语句进行条件判断后,直接执行到程序的条件语句,分支多时效率更高
8.3循环结构
8.3.1for循环
for(初始化变量;条件表达式;操作表达式) {
//循环体
}
8.3.2断点调试
f12 sources f11下一步
观察
watch
8.3.3for循环重复执行不同代码
for (var i=1; i <= 100; i++) {
console.log('今年' + i + '岁了');
}
8.3.4for循环重复某些操作:求1-100之间所有整数的累加和
var sum = 0;
for (var i = 1; i <= 100; i++){
sum += i;
}
alert('总和为:' + sum);
8.3.5求1-100之间所有能被3整除的数字的和
var result = 0; for(var i = 1; i <= 100; i++){ if(i % 3 == 0){ result += i; } }
8.3.6求一个班学生总成绩和平均成绩
var count = prompt('请输入班级人数');
var sum = 0;
var average = 0;
for (var i = 1; i <= count; i++){
sum += parseFloat(prompt('请输入第' + i + '个学生成绩!'));
//注意类型转换!
}
average = sum / count;
alert('总成绩是:' + sum);
alert('平均成绩是:' + average);
8.3.7一行打印n个星星
追加字符串的方式,每循环一次追加一个星星
var num = prompt('请输入星星个数!');
var str = '';
for(var i = 0; i <= num; i++){
str = str + '★'
}
console.log(str);
8.3.8双重for循环
for(外层的初始化变量;外层的条件表达式;外层的操作表达式){
for(里层的初始化变量;里层的条件表达式;里层的操作表达式){
//循环体
}
}
注意:外层循环循环一次,里层执行全部
8.3.9打印5行5列星星
双重for循环,记得换行\n
8.3.10打印五行倒三角形星星
//me的一些弱智行为
var rows = prompt('请输入行数!');
var str = '';
var cols = rows;
for(var i = 1; i <= rows; i++){
for(var j = 1; j <= cols; j++){
str = str + '★'
}
str += '\n'
cols --
}
alert(str);
老师:
var str = '';
var cols = rows;
for(var i = 1; i <= 10; i++){
for(var j = i; j <= 10; j++){
str = str + '★'
}
str += '\n'
}
alert(str);
8.3.11九九乘法表案例
var str = '';
for(var i = 1; i <= 9; i++){
for(var j = 1; j <= i; j++){
str += j+ 'x' + i + '=' + i * j+ '\t';
}
str += '\n';
}
alert(str);
8.3.12while
var num = 1;
while(条件表达式){
// 循环体;
num++;
}
里面应该有计数器 和 操作表达式 防止死循环!
while 和 for 循环的区别是:while能够实现更加复杂的判断条件!
8.3.13do while
do{
// 循环体;
} while(条件表达式)
// 和while的区别是,do while 至少执行一次!
8.3.14continue与break
continue 跳出本次循环 继续执行剩余次数的循环!
// 求1-100之间 能被7整除之外的整数 的和
for(i=1;i<=100;i++){
if(i % 7 ==0)
continue;
}
break 跳出整个循环!
8.3.15简易ATM机
var money = 100;
do{
var choose = prompt('请选择您的操作:'+'\n'+'1.存钱'+'\n'+'2.取钱'+'\n'+'3.显示余额'+'\n'+'4.退出'); switch(choose){
case '1':
var saveMoney = prompt('请输入您要存多少钱!');
money += parseFloat(saveMoney);
alert('您的余额为:'+ money);
break;
case '2':
var useMoney = prompt('请输入您要取多少钱!');
money -= parseFloat(useMoney);
alert('您的余额为:'+ money);
break;
case '3':
alert('您的余额为:'+ money);
break;
case '4':
alert('您已成功退出!');
break;
default:
break;
}
} while(choose!='4')
9.命名规范以及语法格式
9.1标识符命名规范
变量、函数的命名必须有意义
变量的名称一般用名词
函数的名称一般用动词
9.2操作符规范
操作符的左右两侧有空格
9.3单行注释规范
// 单行注释前面注意有个空格
9.4其他规范
for {} if () 空格 else {}
10.数组
数组可以把一组相关的数据一起存放,并提供方便的访问方式
数组是一组数据的集合,每个数据存储在单个变量下,称之为元素。
数组中可以同时存放任意类型的数据!
10.1创建数组的方式
10.1.1new关键字 + Array构造函数创建数组
// var 数组名 = new Array();
var arr = new Array();
arr.push(1);
console.log(arr);
10.1.2利用数组字面量创建数组
var 数组名 = [] ;//创建一个空的数组
var arr = [1,2,'pink',true]; //数组的 初始化,四个数组元素
10.2获取(访问)数组中的元素
10.2.1通过数组的索引
数组的索引是用来访问数组元素的序号,数组下标从0开始
格式:
数组名[索引号]
如:
console.log(arr[0]);
//如果没有数组下标的数组元素,输出的结果是undefined
10.3遍历数组
//for循环遍历
var arr = ['red', 'blue', 'green'];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
//index = length - 1
} //forEach
10.4课题案例
10.4.1数组求和及平均值
//数组:[2,6,1,7,4]
var arr = [2, 6, 1, 7, 4];
var sum = 0;
var average = 0;
var count = arr.length;
for (var i = 0; i < count; i++) {
sum += arr[i];
}
average = sum / count;
console.log(sum);
console.log(count);
10.4.2筛选数组最大值
var arr = [2, 6, 1, 77, 52, 25, 7];
var max = 2;
//把数组中的第一个值赋给max,如果写0,数组里全是负数就错啦!
for (var i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
console.log(max);
10.4.3把数组转换为一个字符串
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);
10.5数组中新增元素
10.5.1修改length长度
不赋值时,数组元素默认为undefined,长度为0
10.5.2通过修改索引号新增数组元素
arr[3] = 'pink';
//没有被占用的索引号相当于追加,有了相当于替换
10.5.3新建一个数组里面存放1~10
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = i + 1;
}
10.5.4筛选数组中大于10的数
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
var index = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] >= 10) {
newArr[index++] = arr[i];
//此种更可!
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
10.5.5删除指定数组元素
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i];
} else {
continue;
}
}
console.log(newArr);
10.5.6翻转数组
var arr = ['red', 'green', 'blue', 'pink', 'purple'];
var newArr = [];
var j = arr.length - 1;
for (var i = 0; i < arr.length; i++) {
newArr[j] = arr[i];
j--;
}
console.log(newArr);
10.6冒泡排序
一次比较两个元素,重复进行到没有再需要交换
var arr = [5,4,3,2,1];
var temp = 0;
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]){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
11.函数
封装了一段可以被重复执行调用的代码块
11.1函数的使用
11.1.1声明函数(function关键字直接声明)
function 函数名 (){
//函数体
}
注意:
function是声明函数的关键字 全部小写
函数名一般是动词
函数不调用自己不执行
11.1.2调用函数
函数名();
11.2函数的参数
形参和实参,实现函数重复不同的代码
函数的参数可以有也可以没有,数量不限
11.2.1形参
在声明函数的小括号里,是形式参数
function 函数名(形参1,形参2…){}
11.2.2实参
在函数调用的小括号里,是实际的参数,函数调用时传递给形参
函数名(实参1,实参2…);
11.2.3求任意两个数(之间)的和
//求任意两个数的和
function getSum(num1, num2) {
console.log(num1 + num2);
}
getSum(5, 6);
求任意两个数之间的数的累加和
function getSums(num1, num2) {
var sum = 0;
for (var i = num1; i <= num2; i++) {
sum += i;
}
console.log(sum);
}
getSums(5, 7);
11.2.4形参和实参个数不匹配问题
- 如果实参的个数和形参一致,则正常输出结果
- 如果实参的个数多余形参的个数,则正常输出结果,会取到形参的个数为止
- 如果实参的个数小于形参的个数,未接收到实参的形参的值是undefined(数字型与undefined相加结果是NaN)
11.3函数的返回值
因为在函数体内输出是不应该的,而应该返回值给调用者
11.3.1return语句
function 函数名(){
return '需要返回的结果';
}
函数名();
//函数名() = return后面的结果 赋值操作
11.3.2利用函数求任意两个数中的最大值
function getMax(num1, num2) {
return num1 > num2 ? num1 : num2;
}
console.log(getMax(9, 8));
11.3.3利用函数求任意一个数组中的最大值
function getMax(arr) {
var max = arr[0];
for (var i = 1; i <= arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
var re = getMax([5, 2, 99, 101, 67, 77]);
//实际开发中用一个变量接收函数的返回结果
console.log(re);
11.3.4return 终止函数
- return执行后,函数就不再继续执行
- return只能返回一个值
function fn(num1,num2){
return num1,num2;//返回的结果是最后一个值
}
console.log(fn(1,2));
- 只能返回一个值,但是可以通过数组包含!
function getResult(num1,num2){
return [num1+num2,num1-num2];
}
console.log(fn(1,2));
再通过遍历出数组结果即可
11.3.5如果函数没有return 则返回undefined
函数都有返回值!但看有无return终止函数!
11.3.6break、continue、return的区别
- break :结束当前的循环体 (for 、while)
- continue: 跳出本次循环,执行下一次循环(for 、while)
- return :不仅可以退出循环,还能返回return语句中的值,同时还可以结束当前函数体内的代码
11.4arguments的使用
11.4.1arguments的定义
当我们不确定有多少个参数传递时,可以用arguments(只有函数有的对象)来获取(实际上是当前函数的一个内置对象,其中存储了传递过来的所有实参,展示形式是一个伪数组)
伪数组的特性:
- 具有数组的length属性
- 按照索引的方式进行存储
- 他没有真正数组的一些方法 如:pop()、 push()等
function fn() {
console.log(arguments);
//arguments = [1,2,3]
}
fn(1,2,3);
//可以通过数组的方式遍历arguments
11.4.2利用函数求任意个数的最大值
function getMax() {
var max = arguments[0];
for (var i = 0; i < arguments.length; i++) {
if (max < arguments[i]) {
max = arguments[i];
}
}
return max;
}
var re = getMax(111, 888, 9);
console.log(re);
11.5函数案例
11.5.1利用函数封装方式,翻转任意一个数组
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
//从旧数组的最后一个开始遍历
newArr[newArr.length] = arr[i];
//新数组从第一个开始
}
return newArr;
}
var re = reverse([1, 5, 4, 6]);
console.log(re);
11.5.2函数封装冒泡排序
function sort(arr) {
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]) {
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);
11.5.3判断闰年
function isRunYear(num) {
var flag = false;
if ((num % 4 == 0 && num % 100 != 0) || num % 400 == 0) {
flag = true;
}
return flag;
}
var re1 = isRunYear(2004);
var re2 = isRunYear(2009);
console.log(re1);
console.log(re2);
11.5.4函数可以调用另外一个函数
function fn1() {
console.log(11);
fn2(); //② 调用另一个函数
}
fn1(); //①
function fn2() {
console.log(22);
}
11.5.5用户输入年份,输出当前年份2月份的天数
//如 :如果是闰年,则为29;如果是平年,则为28
function isRunYear(num) {
var flag = false;
if ((num % 4 == 0 && num % 100 != 0) || num % 400 == 0) {
flag = true;
}
return flag;
}
function backDay() {
var year = prompt('请您输入年份:');
if (isRunYear(year)) {
alert(year + '年2月份的天数为:29天!');
} else {
alert(year + '年2月份的天数为:28天!');
}
}
backDay(); //①
11.6函数的四种声明方式
11.6.1利用函数关键字自定义函数(function)
function() {};
11.6.2函数表达式
var fn = function() {};
注意:
- 匿名函数 变量名不是函数名
- 函数表达式声明方式和变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
- 变量名可以来调用函数传递参数 变量名(实参);
11.6.3立即执行函数
立即执行函数:声明一个函数,并马上调用这个匿名函数就叫做立即执行函数;即立即执行函数是定义函数以后立即执行该函数。
//function这个关键字既可以当做语句,也可以当做是表达式
//1.被js引擎当做语句,即当做是函数声明,函数声明不应该以圆括号结尾 function() {};
//2.被js引擎当做表达式 var fn = function() {};
//为了避免解析上的歧义,JS引擎规定,如果function出现在行首,一律解析成语句,此时再在后面之间加(),会报错。
//为了不被解析成语句,就需要不让function在行首,于是有了以下两种写法:
((function() {})());
((function() {}))();
注意:
立即执行函数本质是声明了一个匿名函数,传参直接写在后面的圆括号里即可。
立即执行函数会形成一个单独的作用域,我们可以封装一些临时变量或者局部变量,避免污染全局变量。
即,在立即函数中,即使变量提升,也只提升到当前单独的作用域的最前面,而不是全局作用域的最前面。
11.6.4new + Function构造函数(ES6)不推荐
let sum = new Function('a', 'b', 'return a + b');
alert( sum(1, 2) ); // 3