您的位置:首页 > Web前端 > JavaScript

函数(Function)---声明、定义、事件、作用域、递归

2017-07-30 14:56 435 查看

了解函数

函数就是把特定功能的代码抽取出来并进行封装,用来重复执行一些功能,并起个名字(函数名)。函数对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行

使用函数的好处,为什么要使用函数

函数可以重复执行某一部分代码(通过函数名调用)

使程序变得更简短而清晰

有利于程序维护

什么时候需要函数

当相同的代码出现多次时

当需要提取公共代码时

封装:1-100随机数,把重复性的代码写到函数中

<script>

/*
封装:1-100随机数
把重复性的代码写到函数中
* Math.random();//0-1(不等于1)
*/

function randomNumber(){
var number = parseInt(Math.random()*100)+1;
console.log(number);
}

// var number1 = parseInt(Math.random()*100)+1;
// var number2 = parseInt(Math.random()*100)+1;

// 函数的执行
// 格式:函数名()
randomNumber();
randomNumber();
randomNumber();
randomNumber();

</script>


函数的声明

仅仅是将函数保存到内存中

函数声明注意事项:

避免与变量重名

声明提前

浏览器在逐行解析代码前,会把变量声明和函数声明事先保存在内存中

函数声明

变量声明(变量声明但不赋值,默认值为undefined)

函数的定义

关键字声明(声明式)

函数的声明会提前 ==> 解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);

//格式:funtion 函数名(){}
function show(){}


函数表达式(赋值式)

//show();不能这样写
//格式:
var show = function(){}
show();
/*不能在赋值式之前使用show(),show()在前面时只声明了show(相当于var show;)但是show未被赋值此时show的值为undefined,undefined()不是一个函数会报show is not a function错*/


报错会阻止代码向下执行

* 浏览器解析代码步骤

1. 把变量声明和函数声明事先保存到内存中

2. 逐行执行代码

* show2 is not a function
* 单词写错
* show2不是一个函数


函数的执行

1.手动调用
sum();


2.事件驱动:

格式:元素.事件 = 函数名;

btn.onclick = sum;

常见事件触发函数

onclick:点击事件

ondblclick:双击事件

onmouseover:鼠标移入事件

onmouseout:鼠标移开事件

onchange:内容改变事件(一般用于表单元素)

onkeyup:键盘按键弹起事件

页面加载事件:页面<所有内容>加载完毕后执行(元素、图片、视频、音频..)

console.log(111);
window.onload = function(){
console.log(666)
}
console.log(123);


控制台打印效果是111 123 666

变量的作用域

俗称使用范围,变量能够使用的范围,分<全局作用域>和<局部作用域>

全局作用域

在全局作用域中定义的变量称为全局变量

局部作用域

在局部作用域下定义的变量称为局部变量(函数内定义的变量是局部变量)

变量查找规则

就近原则(如查找变量a)

使用变量a时先从当前函数查找,如果当前函数有变量a则使用;

如果当前函数无变量a,则往父级函数查找,如果找到则使用,并停止查找;

如果在父级函数还是无法找到,则继续往上一层函数查找,以此类推,直到最顶层(全局作用域),如果还是没找到,则报not defined错误;

var className = 'h5_1704';
windows.onload = function(){
var myName = 'emon';
//声明函数
function showMsg(){
var myAge = 22;

document.write('大家好,我叫' + 'myname' + '今年'+myAge+'岁,我在' + className)
}
//调用函数
showMsg();
//在函数外使用函数内的变量会报错
console.log('myName');
//console.log('myAge');
}


作用域链:每个函数在定义时就形成了局部作用域,如果存在多个函数嵌套,他们之间就会建立起某种联系,直到全局作用域,这种联系称之为作用域链。当函数访问变量时,根据就近原则在这个作用域中从内到外查询变量。



声明提前

函数声明提前

变量声明提前

> 声明但没有赋值的变量默认为undefined




/*声明提前
提前到当前作用域顶部
*/
var num = 10;
function sum(){
//var num;
console.log(num);//输出的结果是undefined
var num = 30;
}


函数的参数

函数的参数:局部变量

形参和实参的区别:

形参:声明函数时圆括号定义的变量

实参:函数执行时传入的函数

形参和实参的数量可以不同

arguments

函数内部隐藏的对象(是一个类数组),保存这实参的信息

length:实参的数量

callee:对函数本身的引用

引用数据类型与基本数据类型的传参(引用传递与值传递)

函数作为参数传递

<title>封装一个函数,计算所有传入参数的和</title>
<script>
/*
数组:可以保存多个数据的变量
格式:var arr = [10,20,30]
* 索引:标识某个数据的位置
* 索引值从0开始
* 读取:arr[索引值]
* length:表示数组的长度
*/
var arr = [10,20,30];
//console.log(arr[2])

// 函数内部隐藏的对象(是一个类数组),保存着实参的信息
function sum(){
// console.log(arguments);
// var res = num1 + num2;
// console.log(res);

// 存放结果
var res = 0;

// 循环
for(var i=0;i<arguments.length;i++){
res += arguments[i]
}

console.log(res);
}

// sum(10,20);
// sum(12,11);
// sum(1,2,3);
sum(1,2,3,4,5,6,7,8,9);
</script>


函数中的this

函数中的this是一个关键字,表示当前对象,而当前对象是谁取决于谁调用了这个函数

<script>
window.onload = function(){
//这里的this是window
function showMsg(){
//这里的this指向的是window
console.log(window);
}
showMsg();
}
</script>


函数递归

函数可以自己调用自己,成为函数的递归调用。(要避免死循环)

递归调用的过程:

1.首先去找临界值,即无需计算就获得的值(一般返回该值)

2.找这一次和上一次的关系(一般从后往前找)

3.假设当前函数已经可以使用,调用自身计算上一次的运行结果,再写出这次的运行结果

例1:求任意数字的阶乘

function factorial(n){
if(n==1){
return 1;
}
return n*factorial(--n);
}


例2:递归实现斐波那契数列

function fib(n){
if(n==1 || n==2){
return 1;
}
return fib(n-1)+fib(n-2);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 javascript
相关文章推荐