6、函数
1、认识函数
/*
函数概念:
函数就是把完成特定功能的一段代码[抽象出来],使之成为程序中的一个[独立实体],起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
*/
/*
【注】用户自己起的名字是标识符。 函数名也属于标识符。
1、见名思意
函数语法:
无参函数
函数的声明:相当于写了一份说明书,给计算机一本书,这个代码写在第41页上。
格式:
function 函数名(){
函数体;(一段代码)
}
函数的调用:
格式:函数名();
【注】封装函数相当于写一份说明书。
*/
/*function print(){
for(var i = 0; i < 10; i++){
document.write("hi world! <br/>");
}
}*/
var print = function(){
for(var i = 0; i < 10; i++){
document.write("hi world! <br/>");
}
}
print();
//员工教用户使用手机
/*for(var i = 0; i < 10; i++){
document.write("hello world! <br/>");
}*/
/*
100行代码以后
*/
print();
/*
*/
print();
print();
print();
/*
1、代码太乱
2、重复代码太多。
3、后期代码维护,相当困难
4、太难阅读了。
*/
/*
使程序变得更简短而清晰
有利于程序维护
可以提高程序开发的效率
提高了代码的重用性(复用性)
*/
2、函数
1、内置函数/系统函数
// alert(); doucment.write() Math.random() Math.pow()
2、用户自定义函数
【重点】函数名的声明,除了要遵守标识符声明的规则以外,还要遵守以下规则。
<1>函数名必须体现其功能
<2>函数的功能尽可能保证单一。
【注】函数是当它被调用时执行的可重复使用的代码块。
可以重复使用的说明书。
无参函数
/* function print(){
for(var i = 0; i < 10; i++){
document.write("hi world! <br/>");
}
}*/
带参的函数
形参:形式参数
声明函数的时候,用的假设的参数,叫做形参。
实参:实际参数
调用函数的时候,用的实际参数,叫做实参。
【注】调用函数的时候,如果使用实参。形成传参(传递参数)。
传递参数:用实参给形参赋值。
/*
计算两个数之和
*/
function add(num1, num2){ //形参 num1 = 10, num2 = 20;
alert(num1 + num2);
}
//调用
add(10, 20); //实参
add(30, 40);
3、返回值
【注】有返回值,因为我们要在别的地方是用函数调用的执行结果。
通过关键字return。
函数(就是表达式):
1、功能
2、值
【注】return 后面的值,
return后面可以跟任意表达式。
/*
计算两个数之和
*/
/*
函数的设计:
1、形参如何确定,分析该函数中有哪些值不确定的。
2、函数结果,就直接看return后面跟了什么,函数调用的值,就是return后面所跟表达式的值。
*/
function add(num1, num2){ //形参 num1 = 10, num2 = 20;
// return num1 + num2;
/*
100行代码
*/
return "hello world";
}
//调用
var res = add(10, 20); //实参
alert(res);
add(30, 40);
4、arguments
封装一个函数,sum求和的函数,求任意个数的和。
arguments 数组
【注】每一个函数,都内置一个 arguments,是一个数组。
【功能】在调用函数的时候,将传入的实参,保存在arguments这个数组中。
function sum(){
// alert(arguments.length); //object Arguments
/*alert(arguments[0]);
alert(arguments[2]);*/
var sum = 0;
for(var i = 0; i < arguments.length; i++){
sum += arguments[i];
}
return sum;
}
function amass(){
var sum = 1;
for(var i = 0; i < arguments.length; i++){
sum *= arguments[i];
}
return sum;
}
var res = amass(10, 20, 30);
alert(res);
/*var res = sum(10, 20, 30, 40);
alert(res);*/
5、return
return进阶版使用方式。
【重点】函数在执行的时候,如果遇到return就直接终止后续代码运行。
【注】return 代表函数运行结束,return后面的表达式,是函数的结果。
break 用来终止循环。
/* function sum(){
// 100代码
alert(1);
return "我是函数的值";
alert(2);
}
var res = sum();
alert(res);*/
function add(){
var sum = 0;
for(var i = 0; i < arguments.length; i++){
sum += arguments[i];
alert(i);
break;
}
return sum;
}
var res = add(10, 20, 30);
alert(res);
6、练习
/*
编写一个函数,计算两个数字的和、差、积、商
要求:使用传参的形式
*/
/*function counter(num1, operator, num2){
// operator 是字符串 num1 和 num2 数字
//根据传入的 operator,进行不同的运算
// return 结果;
var sum = 0;
if(operator == "+"){
sum = num1 + num2
}else if(operator == "-"){
sum = num1 - num2
}else if(operator == "*"){
sum = num1 * num2
}else{
sum = num1 / num2
}
return sum;
}*/
function counter(num1, operator, num2){
var res = 0;
//1、运算符判断
switch(operator){
case "+":
res = num1 + num2;
break;
case "-":
res = num1 - num2;
break;
case "*":
res = num1 * num2;
break;
case "/":
res = num1 / num2;
break;
default:
alert("error");
break;
}
return res;
}
/*var result = counter(10, "%", 20);
alert(result);*/
/*
编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数求 1+1/3+...+1/n
*/
/*function sum(n){
var sum = 0;
//1、判断n是奇数还是偶数
if( n % 2 == 0){
for(var i = 2; i <= n; i += 2){
sum += 1 / i
}
}else{
for(var i = 1; i <= n; i += 2){
sum += 1 / i
}
}
return sum;
}
*/
function sum(n){
//1、判断n奇偶
if(n % 2 == 0){
var even = 0;
//偶数
for(var i = 2; i <= n; i += 2){
even += 1 / i;
}
return even;
}else{
var odd = 0;
//奇数
for(var i = 1; i <= n; i += 2){
odd += 1 / i;
}
return odd;
}
}
var res = sum(4);
alert(res);
以前的习题封装成函数
function factorialSum(n){
var sum = 0;
for(var i = 1; i <= n; i++){
var amass = 1;
for(var j = 1; j <= i; j++){
amass *= j;
}
sum += amass;
}
return sum;
}
var res = factorialSum(5);
alert(res);
function printDate(year, month, date){
var currentDay = 0;
switch(month){
case 12:
currentDay += 30;
case 11:
currentDay += 31;
case 10:
currentDay += 30;
case 9:
currentDay += 31;
case 8:
currentDay += 31;
case 7:
currentDay += 30;
case 6:
currentDay += 31;
case 5:
currentDay += 30;
case 4:
currentDay += 31;
case 3:
currentDay += 28;
case 2:
currentDay += 31;
case 1:
currentDay += date;
break;
default:
alert("error");
break;
}
if(month > 2){
//判断闰年,+1天
}
return currentDay;
}
var res = printDate(2018, 5, 21);
alert(res);
7、作用域
封装函数 -> 代码段
函数名/变量 -> 存着代码的地址
1、调用函数的时候,在内存中开辟空间运行该函数。一般情况下,空间的大小由在函数内部,声明的变量和形参的数量决定。
2、函数调用结束以后,会把这段内容还给系统,函数内使用的所有的变量和形参会随之销毁。
作用域:
总结:函数大括号,会形成作用域。在这个作用域下声明的变量、和函数的形参叫做局部变量。
【注】在函数声明形参和在该作用域下声明变量等价。
全局变量:声明在全局的变量叫做全局变量,可以在任意函数中调用。
局部变量:声明在局部函数中的变量叫做局部变量,生命周期就是从这个函数开始,到这个函数调用结束。 {}
【注】如果全局变量和局部变量相同,就近原则,谁近用谁。
var a = "省长";
function qingdao(){
var a = "市长";
alert(a);
}
function shibei(){
var a = "区长";
alert(a);
}
function xinqu(){
alert(a);
}
alert(a);
qingdao();
shibei();
xinqu();
/*var a = 10;
function show(){
a++;
alert(a);
}
alert(a); //10
show(); //11
show(); //12
alert(a); //12*/
/*var a = 10;
function show(){
var a = 6;
a++;
alert(a);
}
alert(a); // 10
show(); // 7
show(); // 7
alert(a); // 10*/
/* var a = 10;
function show(a){ // a = 10
a++;
alert(a);
}
alert(a); //10
show(10); //11
show(10); //11
alert(a); //10
*/
【注】如果使用变量的时候,++忘记写var声明变量++,那么++系统会强制声明成全部变量++。
function show(){
a = 10;
}
show();
alert(a);
8、判断是否是正确的年月日
/*
【注】1、函数一定要保证其功能单一性。
2、函数里面调用函数,和在使用系统函数alert一样操作。
*/
/*
年月日分别为自定义函数的参数,判断是否为正确的日期
*/
function isTrueDate(year, month, day){// year = 2018, month = 2 day = 29
//1、判断月份是否是正确的月份
if(month > 12 || month < 1){
return false;
}else{
//2、月份正确,判断该月天数
switch(month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
//31天
if(day < 1 || day > 31){
return false;
}else{
return true;
}
break;
case 2:
//28,判断是否是闰年
var isLeap = leapYear(year);
if(isLeap){
if(day < 1 || day > 29){
return false;
}else{
return true;
}
}else{
if(day < 1 || day > 28){
return false;
}else{
return true;
}
}
break;
default:
//30天
if(day < 1 || day > 30){
return false;
}else{
return true;
}
break;
}
}
}
var res = isTrueDate(2000, 2, 29);
alert(res);
/*
判断是否是闰年
传入:year
传出:true/false
*/
function leapYear(year){ //year = 2018
if(year % 400 == 0 || year % 4 == 0 && year % 100 != 0){
return true;
}else{
return false;
}
}
/*var res = leapYear(2018);
alert(res);*/
9、DOM操作(输入查奇偶)
++document.getElementById(id)
// 获取的是==返回值是标签==input或者button等;
// input.value与button.value获取的是标签的值,==值是字符串类型==;++
<!DOCTYPE html>
Document
</head>
<body>
<input id = "input1" type="text" placeholder="请输入一个数" />
<button id = "btn">判断奇偶</button>
</body>
<script>
// 通过buttonid属性,获取到button这个标签
/*
document.getElementById(id)
参数:id的值
返回值:该id对应的标签。
*/
var oBtn = document.getElementById("btn");
var oInput = document.getElementById("input1");
//oInput.value 获取/设置 输入框的值,值是字符串类型。
// alert(oBtn);
/*
给按钮编写,点击按钮以后要执行的代码。(暂时先用着,咋们还却知识,后续会详细讲解)
点击: onclick
*/
oBtn.onclick = function(){
//写点击按钮以后要执行的代码
// alert("单击了一下");
//获取输入框的值
// alert(typeof Number(oInput.value));
isEvenOrOdd(Number(oInput.value));
}
//判断奇偶函数
function isEvenOrOdd(num){
if(num % 2 == 0){
alert("这是个偶数");
}else{
alert("这是个奇数");
}
}
/*
输入n
点击按钮 输入1~n的和。
*/
</script>
10、DOM操作(输入求和)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<input id = "input1" type="text" placeholder="请输入一个数" />
<button id = "btn">求和</button>
</body>
<script>
// 通过buttonid属性,获取到button这个标签
/*
document.getElementById(id)
参数:id的值
返回值:该id对应的标签。
*/
var oBtn = document.getElementById("btn");
var oInput = document.getElementById("input1");
//oInput.value 获取/设置 输入框的值,值是字符串类型。
// alert(oBtn);
/*
给按钮编写,点击按钮以后要执行的代码。(暂时先用着,咋们还却知识,后续会详细讲解)
点击: onclick
*/
oBtn.onclick = function(){
/*var res = sumFunc(Number(oInput.value));
alert(res);*/
alert(sumFunc(Number(oInput.value)));
}
//求和的函数
function sumFunc(n){
var sum = 0;
for(var i = 1; i <= n; i++){
sum += i;
}
return sum;
}
//判断奇偶函数
function isEvenOrOdd(num){
if(num % 2 == 0){
alert("这是个偶数");
}else{
alert("这是个奇数");
}
}
/*
输入n
点击按钮 输入1~n的和。
*/
</script>
</html>
11、声明提前
var a;
/*
预解析:程序在真正执行之前,会有一个准备状态,这个准备状态叫做预解析。
程序真正运行的时候,所有的空间都分配好了。
声明提前/声明前置
*/
/* alert(a); //undefined
var a = 10;*/
alert(a);
a = 10;
alert(a);
/* var a = 10;
var b = a + 20;
var c = b + 30;*/
//变量的声明都在,都在程序运行的最顶端,所以叫做声明提前。
var a;
var b;
var c;
a = 10;
b = a + 20;
c = b + 30;
12、递归函数
/*
递归:
函数自己调用自己。
递归:循环能做的事,递归全能做,递归能做的事,循环不一定能做。
特点:
1、函数自己调用自己。
2、递归要有参数
3、递归必须有return,但是return后面可以不跟值。
最强王者法则:
1、找出临界值,临界值就是,不用计算,直接心算得出的值。
2、找出第n次和n-1次的关系
3、假设函数已经可以使用,写出n和n-1之间的公式。
sum(n) = sum(n - 1) + n;
sum(100) = sum(99) + 100;
【注】如果有人为,会不会递归,面试官水平可以,对你要求很高。
但是公司禁止使用递归。(写递归,前提,写好绝对没有问题的容错)
*/
/*function sum(n){
if(n == 1){
return 1;
}
return sum(n - 1) + n;
}
alert(sum(100));*/
/*
输入n,输出n和hello world!
*/
function print(n){
if(n == 0){
return; //如果return后面没有值,仅代表终止函数。
}
document.write("hello world!<br />");
return print(n - 1);
}
print(5);
/*function print(n){
for(var i = 0; i < n; i++){
document.write("hello World!<br />");
}
}
print(10);*/
/*
1~n的和
1~n的积
n的阶乘
*/
/*function sumFunc(n){
var sum = 0;
for(var i = 0; i < n; i++){
sum += (i + 1);
}
return sum;
}
alert(sumFunc(100)); //5050*/