函數的定義:
函數是一段能夠反覆調用的代碼塊,函數能夠接受輸入的參數,不一樣的參數返回值也不一樣
通俗的說函數就是一個工具,用來實現某個功能,具備封裝性javascript
函數的聲明有兩種方式:
第一種聲明方法: function命令
function fn () {
}java
第二種聲明方式:函數表達式
須要注意的是,函數表達式聲明函數,表達式後面須要加上分號,表示語句結束
var fn = function () {
};函數
注意:
第二種聲明方式,function後面不帶有函數名,若是加上函數名,該函數名只在函數內部有效,函數外部無效
var print=function x(){
console.log(typeof x);
};
print(); //function
x(); //報錯
這種寫法的用處有兩個,一是能夠在函數體內部調用自身,二是方便除錯(除錯工具顯示函數調用棧時,將顯示函數名,而再也不顯示這裏是一個匿名函數)。工具
函數不得在條件語句中聲明函數
javascript規定不能夠在非函數代碼塊中聲明函數,好比在if語句,try語句中聲明函數
if(false){
function ff(){}
}spa
因爲函數提高,致使上面的if語句無效遞歸
若是要實如今條件語句中聲明函數的目的,必須使用函數表達式聲明法ip
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;
}
}