函数
- JavaScript函数是指一个特定的代码块,可能包含多条语句,可以通过名字来供其他语句调用以执行函数包含的代码块。
- 一般一条语句要使用两次以上,就应该考虑将他封装成组件,函数等。
函数声明:
有三种声明方式:
- 使用构造函数:首先函数也是对象的一种,可以通过其构造函数,使用
new
来创建一个函数对象。(不推荐使用)
var sayHello = new Function('console.log("hello word")');
- 函数声明:使用
function
关键字可以声明一个函数,声明不必放在调用的前面。
//函数声明
function sayHello(){
console.log('hello');
} // 声明函数,函数是不执行的
//函数调用
sayHello(); //调用函数,函数才执行
- 函数表达式,声明必须放在调用前面。
var sayHello = function(){
console.log('hello');
}
sayHello();
传递参数的函数
- 传递单个参数
function fn(name) {
console.log('llll' + name);
}
fn('wwwww');
- 传递多个参数:是按照顺序对应传递的。实参和形参是一一对应的。
function say(name,age,sex){
console.log(name); //lll 23
console.log(age); //23 45
console.log(sex); //d undefined
}
say('lll',23,'d');
say(23,45);
-
arguments
:类数组对象,在函数内部,可以使用arguments
对象获取到该函数的所有传入参数。
function say(name,age,sex){
console.log(name);
console.log(age);
console.log(sex);
console.log(arguments);
console.log(arguments[0]);
console.log(arguments[1]);
}
say('筱琦',23,'女');
TIM图片20190116163332.png
函数的重载
- 在其他强类型语言中,可以有多个同名的函数,但是函数的调用方式或者传递的参数不同,叫函数的重载。
- 在JS中,没有重载!同名函数会覆盖,但可以在函数体针对不同的参数调用执行相应的逻辑。
function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');
1.png
函数的返回值
- 有时候我们希望在函数执行后得到一个结果供别人使用,可以通过
return
来实现。
function sum(a,b){
a ++;
b ++;
return a + b;
}
var result = sum(2,3);
console.log(result); //7
如果没有return,则返回的是undefined
- 注意点:
- 如果不写
return
,函数会默认返回undefined
- 函数在执行过程中,只要遇到return就会立即结束退出函数体。位于return后的任何语句都不会执行。
- return语句后也可以不带有任何返回值,在这种情况下,函数在停止执行后将返回undefined。
- 一个函数中也可以含有多个return语句:
function fn(num1,num2{
if(num1 < num2){
return nun2 - num1
}else{
return num1 - num2
}
}
- 函数返回值和console.log()是两个不同的东西,千万不要
return console.log(age)
。
console.log()本身也是一个函数,被调用之后之后返回值是undefined,作用是用来调试代码,是在控制台展示东西的,并不等于函数的返回值。
var a = console.log(2);
a // undefined,console.log被调用之后返回值是undefined
函数的返回值必须通过return的方式返回出来并赋值给一个变量。
声明前置:在一个执行上下文中或者在一个作用域下,可以进行声明前置。
- var和function的声明前置:
在一个作用域下,var声明的变量和function声明的函数会提前。
console.log(a); //undefined
var a = 3;
console.log(a); //3
sayHello();
function sayHello(){
console.log('hello');
}
相当于:
var a
function sayHello(){}
console.log(a) // undefined
a =3
console.log(a) //3
sayHello();
- 函数表达式
console.log(fn); //undefined
fn(); //报错
var fn = function(){} // 函数表达式和var一个变量没有区别,先有,再用。
相当于:
var fn
console.log(fn) // undefined;
fn() //相当于把undefined调用,所以报错。
- 函数内部的声明前置,函数也是有自己的作用域
function fn(){
console.log(a) //undefined
var a = 3
console.log(a) //3
}
fn()
- 当命名冲突时,先前置,再覆盖。
- 参数重名
function fn(fn){
console.log(fn);
var fn = 3;
console.log(fn);
}
fn(10); //10 3
作用域,只有函数才有作用域
(ES5以前)在JS中只有函数作用域,没有块作用域。
在函数中,作用域是独立的,a只是在函数中被声明了,是局部作用域,在全局作用域下没有a。所以console.log(a)为报错。
function fn(){
var a =1;
if(a > 2){
var b = 3;
}
console.log(b); // undefined
}
fn(); // undefined
console.log(a); // "ReferenceError: a is not defined
var
- 声明一个已经存在的变量,var重复声明一个已经存在的变量,原变量值不变。
function fn(){}
var fn
console.log(fn) // function
var a = 1
var a
console.log(a) // 1
- 不加
var
的作用
function fn(){
a = 1;
}
fn();
console.log(a) // 1
可以看到不写var会声明一个全局的变量,这是在编程中应要避免的,即使真的需要全局变量,也应该在最外层的作用域下使用var声明。
函数的递归
- 自己调用自己
- 设定终止条件
- 优点: 算法简单
- 缺点: 效率低
递归练习
- 求n的阶乘n!
function factor(n){
if (n===1){
return 1; //设置的终止条件
}
return n*factor(n-1); //自己调用自己
}
var result = factor(5);
console.log(result);
- 求 1+2+...+n 的值
function sum(n){
if(n===1){
return 1;
}
return n + sum(n-1);
}
var result1 = sum(10);
console.log(result1);
立即执行函数表达式
- 立即执行函数表达式:
缩写IIFE,是一种利用JavaScript函数生成新作用域的编程方法,也叫自执行函数 - 作用
- 令函数中声明的变量绕过JS的变量置顶声明规则
- 避免新的变量被解释成全局标变量或函数名占用全局变量名的情况
- 在禁止访问函数内变量声明的情况下允许外部对函数的调用
-
实现:因JS里的()里不能包含语句,所以解析器会将()里的代码解析成function表达式并立即执行
-
作用: 隔离作用域
(function(){
var a = 1;
})()
console.log(a); // "ReferenceError: a is not defined
- 其他写法
(function fn1() {})();
// 在数组初始化器内只能是表达式
[function fn2() {}]();
// 逗号也只能操作表达式
1, function fn3() {}();
//感叹号也可以,只不过执行结果为false
!function(){}();
练习-1
console.log(j); //undefined
console.log(i); // undefined
for(var i=0; i<10; i++){
var j = 100;
}
console.log(i); //10
console.log(j); //100
练习-2
fn(); //function
var i = 10;
var fn = 20;
console.log(i); //10,
function fn(){
console.log(i); //undefined
var i = 99;
console.log('i4' + i);// 99 ,此处没有调用fn2(),全局变量没有生效,所以i为99.
fn2(); //unefined
console.log(i); //100 此处值为100,自己调试代码,猜测原因是fn2()已经被调用,所以全局变量生效,所以i赋值为100
function fn2(){
i = 100;
}
}
网友评论