6.函数
6.1函数的概念
为什么需要用函数
循环的嵌套
for(var n=2; n<100; n++){ var m = Math.ceil(Math.sqrt(n)); var found = false; for(var i=2; i< n; i++ ){ if (n % i == 0){ found = true; break; } } if(!found){ document.write(n + "是素数<br>"); } }
这种解决方案程序比较复杂,阅读也比较困难,需要比较高超的技术
应用函数
for(var n=2; n<=100; n++){ if(isPrime(n)){ document.write(n+"<br>") } } function isPrime(n){ var m = Math.ceil(Math.sqrt(n)); for(var i=2; i< n; i++ ){ if (n % i == 0){ return false; } } return true; }
这种解决方案是将一个比较复杂的问题分解为两个较为简单的问题去解决,是用“量”去克服“难”和“大”的问题
这种解决方案给我们提供了一个解决规模大,难度高的问题的解决思路:将它分解为多个规模相对较小,难度相对较低的问题去解决,如果分解后的问题依然规模大或者难度高,可以按照这个思路一直分解下去,直到分解后的问题足够小,简单。归纳起来就是“大事化小”
6.2定义于调用
函数是什么,怎么用
定义:functio isPrime(n){
……
}
function 定义函数的关键字
isPrime 是函数的名字,和变量名一样的命名规则和原则
n 形式参数(形参)
isPrime(12),12就是实际参数(实参)
函数头部,体现的是函数的设计
函数体,体现的是函数的实现过程
设计比实现更重要
案例:验证100以内的数都符合角谷定理
var flag = true; for(var n=2; n<=100; n++){ if(!isJioagu(n)){ flag = false; } } alert("角谷定理"+flag?"成功":"失败"); /* * 功能:判断一个给定的数是否符合角谷定理 * 名称:isJiaogu * 输入参数:待判断的数 * 输出结果:true/false * */ function isJioagu(n){ while(n != 1){ if(n%2 == 0) { n /= 2; }else{ n = n * 3 -1; } } return true; }
验证10000以内哥德巴赫猜想成立
首先假设系统有默认函数
在建立这个函数
完善其输入参数和输出结果
* 假设系统有一个函数能够帮我们判断大于6的偶数能否分解 * * 功能:判断一个数能否分解为两个素数之和 * 名称;canSplit * 输入参数:待分解的数 * 返回结果true/false * */
假设系统有默认的函数,建立的运算过程
var flag = true; for(var n=6; n<=10000; n+=2){ if(!canSplit(n)){ flag = false; break } }
10000,两个数的和
function canSplit(n){ for(var a=2; a<=n/2; a++){ if(isPrime(a) && isPrime(n-a)){ return true; } } return false; } function isPrime(n){ var m = Math.ceil(Math.sqrt(n)); for(var i=2; i< n; i++ ){ if (n % i == 0){ return false; } } return true; }
函数的本质:
直观理解就是实现某个独立功能的代码段,或者说它就是一个数据加工的黑箱子
输入参数→函数名→输出结果
所谓黑箱子,就是我们只关心外面的东西,比方说他是干啥的,需要输入什么,可以得到什么结果,而不关心它里面是怎么工作的。
忽略实现细节
6.3参数传递
所谓参数传递,就是将实参的值传递给形参。
通过调试可以确定形参在函数被调用之前是不存在的,当函数被调用的那一刻,形参被创建,并且把实参的值传递给形参
实参传递有两种方式:值传递和引用传递
<script> var a = 5; increase(a); alert(a); function increase(x){ x++; } </script>
a的值并没有显示预期中的6,还是5.因为形参x和实参a是两个不同的变量,x的变化和a 任何关系
/*引用传递*/ var a = new Object(); a.value = 5; increase(a); alert(a.value); function increase(x){ x.value++; }
a.value没有被显示修改,但是a.value确实是加1了,因为x就是a,或者说x是a的别名,专业一点就叫做引用。
常规类型的参数采用的是值传递,比如:Number,String,Boolean
对象类型采用的是引用传递,Object
如果希望吧参数从函数中带出来,但是函数的返回值只有一个
6.4变量作用域
局部变量,在函数内部定义的变量,这个变量只能够在函数的内部使用,在全局中不能够使用。比如三国中,袁术称帝,只有袁术的人才认为他是皇帝,他发布的命令只有在阵营中才有用,对其他人不认为,他发布的命令没有用
在函数内部定义一个变量,如果没有加上var,那么这个变量被认作为全局变量
function LocalALLVar(){ a = 1; } LocalALLVar(); alert(a);
全局变量,在函数外部定义的变量,这个变量可以在全局进行使用。比如汉朝皇帝发布了命令,那么不管是袁术还是曹操都要听这个命令
冲突处理原则:就近原则
当函数中定义了一个和全局变量名相同的变量,此时在函数中在定义前使用,那么这个变量还是函数变量,为undefined,不使用全局变量
要理解就近原则,而不是从上到下
var a = 1; function aLLVar(){ alert(a); } aLLVar();
局部和全局同时定义了一个相同名字的变量时如何在局部里面访问全局变量?
在局部中给变量加上window的前缀,就可以访问到全局的变量。
var a = 1; function doubleVar(){ var a = 2; var a = 3; //alert(a); alert(window.a); } doubleVar();
在