# 函数对象

# 函数

isNaN(数据)/parseInt/parseFloat/Number/prompt...

函数分为系统函数和自定义函数

function: 功能体,函数(方法),可以接受若干个数据,返回处理的结果。用于封装反复执行的代码——饺子机

# 创建普通函数

function 函数名称() {
  // 函数体  //要封装的代码
}

// 调用
函数名称()
练习
  • 创建函数,封装两个数字相加的和,调用多次。
  • 创建函数,封装两个数字相加的和,调用多次。

# 创建带有参数的函数

function 函数名称(参数列表) {
  // 用于接收传递的数据
  // 函数体;
}

// 调用
函数名称(参数列表) // 实际传递的数据

// 参数: 创建函数时的参数称为形参,调用时参数称为实参,实参会赋值给形参,多个参数之间用逗号隔开。参数可以有0个或者多个,如果形参未被赋值,值为undefined
练习
  • 创建函数,封装计算1~任意数字之间所有整数的和,调用多次。
  • 创建函数,封装计算任意两个年份之间的闰年个数,调用多次。

# 创建带有返回值的函数

function 函数名称(参数列表){
  // 函数体;
  return; // 返回值,函数执行完返回的结果
}

// 调用
函数名称(参数列表)

WARNING

注意事项:
如果函数中没有return,或者return中没有加任何值,返回undefined;执行完return后的代码不会再执行

练习
  • 创建函数,传递两个参数,返回任意两个数字的最大值。
  • 创建函数,传递三个参数,返回任意三个数字的最大值
  • 创建函数,传递订单的状态码,返回对应的汉字状态
    • 1-待付款 2-待发货 3-运输中 4-已签收 5-已取消 其它-无法追踪
  • 创建函数,传递任意一个年份,返回是否为闰年 是->true 不是->false
  • 创建函数,传递任意一个年份,如果是闰年返回366,否则返回365
  • 计算1~任意数字之间所有整数阶乘的和
    • 计算任意数字的阶乘。 n~1之间所有整数的乘积
      1 + 2 + 3 + 4 + 5
      4! = 4 * 3 * 2 * 1
      5! = 5 * 4 * 3 * 2 * 1 
    

# 对比 breakreturn 用法

TIP

break用于结束switch语句,还可以用于提前结束循环。
return 用于函数中返回值,可以结束函数后续代码执行。

# 作用域

变量或者函数的可访问范围,分为两种

TIP

全局作用域:在全局使用var声明的变量,可以在任意范围访问到
函数作用域:在函数使用var声明的变量,只能在函数内部访问到

WARNING

注意事项:
在函数内不使用var声明的变量,是全局变量,可以在函数外部访问——不推荐这样写。

  • 变量提升

JS程序执行前,会将使用var关键字声明的变量提升到所在作用域的最前边,但是赋值还是在原来的位置。

  • 函数的作用域

函数的可访问范围,在全局作用域下创建的函数可以在任意位置访问;在函数作用域下创建的函数只能在函数内部访问。

  • 函数提升

和变量提升一样,JS程序执行前,会把function关键字创建的函数提升到所在作用域的最前边,在调用的时候才会执行函数体中的代码

# 递归

在函数的内部调用自身,默认是一个无限循环。

使用:要有跳出条件,结合者return使用

// 斐波那契数列
function box(m) {
  if (m == 1 || m == 2) {
    return 1;
  }

  return box(m-1)+box(m-2);
  // 除去1和2的两种情况,递归斐波那契数列一行代码就能搞定,但是递归性能是大大不如函数的。
}
练习
  • 使用递归计算1~任意数字之间所有整数的和

# 匿名函数

// 没有名称的函数    匿名函数自调用
//  目的:创建函数作用域包裹起来,防止污染全局
(function(形参列表){
  // 函数体中的变量和函数不能被外部访问
})(实参列表);


// 创建函数
// 函数声明
function fn1(){   }

// 函数表达式
var fn2=function(参数){
  // 函数体;
}
// 变量名就是函数的名称

对比函数声明和函数表达式的区别

函数声明创建函数存在提升,可以在任意位置创建;
函数表达式使用变量创建的,只是存在变量提升,不存在函数提升,只能先创建,再调用。

练习
  • 使用函数表达式创建函数,计算任意两个数字之间所有整数的和

# 回调函数

把匿名函数以实参的形式传递,意味着形参就是传递的匿名的函数名称

function fn(a){
  //调用fn的时候,匿名函数赋值给参数a,a就是函数名称
  a()
  //执行传递的匿名函数函数体中的代码
}
练习
  • 创建函数,传递两个参数,实参使用匿名函数的形式传递,在匿名函数的函数体中添加若干行代码;在函数中执行匿名函数体中的代码。

# 全局函数

parseInt()/parseFloat()/isNaN()
encodeURI()  // 对网址中的汉字进行编码
decodeURI()  // 对已经编码网址进行解码
isFinite()   // 判断一个值是否为有限值  
             // 是->true 不是-false
2/0 ->Infinity(无穷)   0/2 ->0
eval()       // 执行字符串中的表达式
eval('1+2')  //3

# 对象

属于引用类型数据

对象:是一组属性(property)和方法(method)的集合

一台电脑: 属性有颜色、尺寸、品牌、内存大小...方法有看视频、上网、敲代码..
一辆汽车: 属性有颜色、长度、品牌、空间大小...方法有代步,拉货、撞人...
万物皆对象

# JS中的对象

内置对象: JS提供的
宿主对象: 根据不同的执行环境划分
自定义对象: 自己创建的对象

# 创建自定义对象

对象字面量
内置构造函数
自定义构造函数

# 对象字面量创建对象

使用大括号创建空对象
属性名和属性值之间用冒号隔开
多组属性之间用逗号隔开
属性名中的引号可加可不加,如果含有特殊字符必须加

var phone = {
  color: '黑色',
  brand: '华为',
  no: 'P30',
  size: 5.9
}
练习
  • 创建一个员工对象,包含编号,姓名,工资,生日
  • 创建一个手机对象,包含颜色,尺寸,品牌

# 访问对象中的属性

对象.属性名
对象['属性名']

// 如果访问的属性名不存在,返回undefined

var phone = {
  color: '黑色',
  brand: '华为',
  no: 'P30',
  size: 5.9
}

console.log(phone.color)
console.log(phone['color'])
练习
  • 创建图书的对象,包含编号、标题、作者、价格,修改图书的价格,打印图书的作者,添加图书的出版社。

# 内置构造函数创建对象

new Object()  // 创建一个空对象
// 需要单独为对象添加每一个属性

//使用内置构造函数创建对象
var car = new Object();
//添加属性
car.brand = '五菱宏光';
car.color = '白色';
car['price'] = 60000;
练习
  • 创建一个笔记本对象,包含编号,标题,价格,规格

# 遍历对象中的属性

访问对象中的每一个属性

for(var key in 对象){
  // key  代表对象中的每个属性名
  // 对象[key]  通过属性名或者对应属性值
}


// 练习:创建对象,包含有若干个成绩,遍历对象属性,计算总成绩
var score={
  chinese: 87,
  math: 95,
  english: 99,
  sport: 89
};
var sum = 0;

for(var key in score){
  // console.log(key,score[key]);
  // 把每一个成绩加到 sum 中
  sum += score[key]
}

console.log(sum);
练习
  • 创建对象,包含有若干个成绩,遍历对象属性,计算总成绩

# 课后任务

练习
  • 创建对象,包含若干个年龄,获取平均年龄,把年龄大于20岁的打印出来。
  • 预习js中的数组