一、函数基础与种类

数学函数:输入x 得出y
函数式编程:用函数封装功能模块,代码复用,解耦合
三种情况想完成一个功能,其实是一个功能
这就有耦合的情况,重复代码块太多了
高内聚低耦合,让代码块重复更少
解耦合,函数一般比较常用
=> 等同于的意思
耦合 : 重复的代码太多了,代码的重复度太高了
高内聚:强功能性,高独立性
低耦合:把重复的代码提取出来 -> 模块的单一责任制
解耦合:使用函数可以很好的进行解耦合(减少重复)
最基本的函数写法 - 函数
function test (参数){函数执行语句}
函数名的命名规则
不能数字开头
字母 数字 下划线 $ 组成
小驼峰命名法 myFunction
函数作用:功能的封装、解耦合。
函数名命名和变量名规则相同。
定义函数的语法:
// 函数声明的方式定义function name(arg1, arg2) {...}// 函数表达式的方式定义//匿名函数表达式 函数字面量//匿名函数var name = function (arg1, arg2) {...}var name = function name2(arg1, arg2) {...}//name2可以省略
var test = function test1() {var a = 1,b = 2;// 可以在函数内部调用test1()console.log(a, b);}// 如果是匿名函数,则打印testconsole.log(test.name); // 'test1'test(); // 1 2
函数只有被调用时才会执行,不调用时不会
二、形实参及映射
function 函数名 参数(可选) 返回值(可选) return代码自动在后面加上,没有返回值返回undefined
2.1 形实参
2.1.1 形参
2.1.2 实参
函数调用时传入的参数。
实际参数 实参
false NaN
什么数据类型都可以传过去
var aa = Number(window.prompt('a'));var bb = Number(window.prompt('b'));// a, b 形参function test(a, b) {console.log(a + b);}// aa,bb 实参test(aa, bb);

形参实参,形参是占位符
实参只有在test(aa,bb)函数运行时的赋予的值,aa、bb都是实参
a、b以及函数里面的都是形参,因为函数不运行,不知道传入的是什么参数,所以用形参来占位指代,相当于f(x)=2x的x,指代要传入的值
2.1.3 形式参个数可以不相等

不会报错

1 2
function test(a, b) {// 函数形参个数console.log(test.length); // 2// 函数实参个数console.log(arguments.length); // 3}test(1, 2, 3);
2.2 arguments
1.类数组对象。
2.存储实参列表。
3.可以在函数内部修改传入的实参值。
4.实参未传入时,在函数内部给行参赋值无效。



在函数内部可以更改实参的值,

undefined
没有声明b,b是undefined,没有声明,不能赋值,所以arguments[1]是undefined
argument[0]与a不是一个东西,存储地方不同,但有映射关系
a=3 a存栈内存里,argument[0]存堆内存里
实参与形参是不同的量,存在不同的地方,但是系统里有映射关系,无论实参怎么赋值,形参都会改变,但一定形参数组里面有对应的值才行,如果没有对应的值没有用,有映射关系,给形参赋值实参也会改变
参数有没有映射关系看一开始函数运行时给他赋予参数了没有,即使是undefined也行,不写写个,不行
function test(a, b, c) {a = 3;c = 5;console.log(arguments[0]); // 3console.log(arguments[2]); // undefined}test(1, 2);
function test(a, b, c) {arguments[0]=6;console.log(a)//6a = 3;c = 5;console.log(arguments[0]); // 3console.log(arguments[2]); // 5}test(1, 2,undefined);
function test(a, b, c) {arguments[0]=6;console.log(a)//6a = 3;c = 5;console.log(arguments[0]); // 3console.log(arguments[2]); // undefined}test(1, 2,);
2.3 return语句
1终止函数执行
2返回相应的值
function test(name) {return name || '你没有填写姓名';}console.log(test()); // '你没有填写姓名'
根据输入实参,求累加和
// 一个函数被调用时,累加它的实参值function sum() {var _length = arguments.length;var sum = 0;for (var i = 0; i < _length; i++) {sum += arguments[i];}console.log(sum);}sum(1, 2, 3);
三、变量类型
3.1 全局变量
1.在全局环境下声明的变量在任何地方都可以访问。
2.在函数内定义变量时省略var操作符,可以创建一个全局变量。只要调用一次该函数,就会定义这个变量,并且可以在函数外部访问到。
3.2 局部变量
使用var操作符定义的变量会成为包含它的函数的局部变量,该变量将在函数退出时销毁。
// 全局变量a = 1;function test1() {// 局部变量var b = 2;console.log(a, b); // 1 2// 重新赋值全局变量a a -> 4a = 4;function test2() {// 局部变量var c = 3;// 重新赋值test1内的变量b b -> 5b = 5;console.log(b); // 5}test2();// test2函数运行完时局部变量c被销毁console.log(c); // ReferenceError}test1();

函数封装的是一个一个的功能,功能是输入x,输出y,输入就是参数,输出就是return
函数最好都有参数与返回值
四、作业
4.1 定义一个函数,从wp接收一个饮料的名称,函数返回对应的价格
function test1(name) {switch (name) {case '可乐':console.log('3¥');break;case '矿泉水':console.log('1¥');break;case '脉动':console.log('5¥');break;case '营养快线':console.log('4¥');break;default:console.log('无');}}var name = window.prompt('请输入饮料的名称');test1(name);
4.2 定义一个函数,从wp接收第一个数,接收一个运算符号(+ - * / %),接收第二个数,利用这个函数做运算,并返回运算结果
function test2(value1, type, value2) {switch (type) {case '+':console.log(value1 + value2);break;case '-':console.log(value1 - value2);break;case '*':console.log(value1 * value2);break;case '/':console.log(value1 / value2);break;case '%':console.log(a % b);break;default:console.log('输入格式错误');}}var value1 = Number(window.prompt('请输入第一个数字'));var type = window.prompt('请输入运算符');var value2 = Number(window.prompt('请输入第二个数字'));test2(value1, type, value2);
4.3 定义一个函数,从wp接收一个n,算出n的阶乘,不能用for循环
function test3(n) {if (n < 0) {return '请输入一个正整数';}if (n === 0) {return 1;} else if (n > 0){return test3(n - 1) * n;}}var n = parseInt(window.prompt('请输入一个正整数'));console.log(test3(n));
4.4 定义一个函数,从wp接收一个n,算出斐波那契数列的第n项,不能用for循环
function test4(n) {if (n <= 0) {return 0;}if (n === 1 || n === 2) {return 1;} else {return test3(n - 1) + test3(n - 2);}}var n = parseInt(window.prompt('请输入一个正整数'));console.log(test4(n));
