函数学习笔记
函数的定义:
函数是一段可以反复调用的代码块,函数可以接受输入的参数,不同的参数返回值也不同
通俗的说函数就是一个工具,用来实现某个功能,具有封装性
函数的声明有两种方式:
第一种声明方法: function命令
function fn () {
}
第二种声明方式:函数表达式
需要注意的是,函数表达式声明函数,表达式后面需要加上分号,表示语句结束
var fn = function () {
};
注意:
第二种声明方式,function后面不带有函数名,如果加上函数名,该函数名只在函数内部有效,函数外部无效
var print=function x(){
console.log(typeof x);
};
print(); //function
x(); //报错
这种写法的用处有两个,一是可以在函数体内部调用自身,二是方便除错(除错工具显示函数调用栈时,将显示函数名,而不再显示这里是一个匿名函数)。
函数不得在条件语句中声明函数
javascript规定不可以在非函数代码块中声明函数,比如在if语句,try语句中声明函数
if(false){
function ff(){}
}
由于函数提升,导致上面的if语句无效
如果要实现在条件语句中声明函数的目的,必须使用函数表达式声明法
if(false){
var ff1=function(){
}
}
ff1(); //报错
函数名的提升:
javascript把函数名视同为变量名,在预解析的时候会把整个函数提升到代码头部,所以function命令声明的函数,可以先调用后声明
fn(); //不会报错
function fn(){
console.log(1);
}
但是函数表达式声明的函数却不可以,因为js预解析的时候只是把变量声明提到了代码的最顶部,并没有把赋值提升,在没有赋值之前,变量的值为undefined
fn1(); //报错 fn1不是一个函数
console.log(typeof fn1); // undefined
var fn1=function(){
console.log(2);
}
注意:同时采用赋值语句和function命令声明同一个函数,最后总是采用赋值语句声明的函数
递归函数:
函数的内部可以调用自身,这就是递归函数
function fib(num){
if(num===0){
return 0;
}
if(num===1){
return 1;
}
return fib(num-2)+fib(num-1);
}
函数中的return语句
函数体内部的return语句,表示返回。javascript引擎遇到return语句,就返回return后面的那个表达式的值,后面即使还有语句,也不会得到执行,也就是说return语句后面的那个表达式值就是函数的返回值,return语句不是必须的,如果不写,函数就不返回任何值,或者返回undeifned
函数的属性和方法:
1.函数的length属性返回的是函数预期返回的参数的个数,也就是函数声明时候参数的个数
function fn(a,b){
return a+b;
}
console.log(fn.length);
fn(1);
console.log(fn.length);
fn(1,2,3);
console.log(fn.length);
2.name属性返回的是紧跟在function关键字后面的那个函数名
function f1(){
}
console.log(f1.name); //f1
//将一个匿名函数赋值给一个变量
var f2 = function () {};
//那个这个函数的name属性值在ES5下总是返回一个空字符串
console.log(f2.name); //""
//在ES6下做了修改,返回的是实际的函数名
console.log(f2.name); //f2
//真正的函数名还是f3,myName这个名字只在函数体内部可用
var f3=function myName(){
}
console.log(f3.name); //myName
3.函数的toString方法返回函数的源码
function f1(){
console.log(123);
}
console.log(f1.toString());
function f2(){/*
这是一个
注释
*/}
console.log(f2.toString());
实现多行字符串
function multiline(fn){
var arr=fn.toString().split("\n");
return arr.slice(1,arr.length-1).join("\n");
}
console.log(multiline(f2));
document.body.innerHTML="<pre>"+multiline(f2)+"</pre>";
函数的作用域:
作用域(scope)指的是变量存在的范围。Javascript只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。
在函数外面声明的变量就是全局变量 可以在函数内部读取
var a=12;
function fn(){
console.log(a);
}
fn(); //12
在函数内部定义的变量,称为局部变量,在函数外面读取不到
function fn(){
var c=23;
}
console.log(c); //报错
函数内部定义的变量,会在作用域内覆盖同名的全局变量
var f=12;
function f5(){
var f=44;
console.log(f);
}
f5(); //44
console.log(f); //12
对于var声明的变量来说,只有在函数内部声明的变量才是局部变量,其他区块声明的都是全局变量
if(true){
var a=12;
}
console.log(a); //12
函数本身的作用域:
函数本身也是一个值,也有自己的作用域,函数的作用域就是其声明时所在的作用域,与其运行时所在的作用域无关
var s=12;
function fn(){
console.log(s);
}
function fn1(n){
var a=24;
n();
}
fn1(fn); //12
函数体内部声明的函数,作用域绑定函数体内部。
function f2(){
var n=33;
return function f3(){
console.log(n);
}
}
var n=99;
f2()(); //33
函数内部变量的提升:
和全局作用域一样,函数内部的作用域也会产生变量提升的现象,var声明的变量,不论在什么位置,变量声明都会被提升到函数体内部的顶部
function fn(x){
if(x>100){
var temp=x-100;
}
}
//等同于:
function fn(x){
var temp;
if(x>100){
temp=x-100;
}
}