考慮一個函數傳統的方式是 ,聲明一個函數,在它內部添加代碼。標題這裏作了一個角度的切換:在編寫代碼外圍包裝一個函數說明,去「隱藏」這段代碼。前端
咱們看第一個代碼片斷:git
function doSomething(a) {
b = a + doSomethingElse( a * 2 );
console.log( b * 3 );
}
function doSomethingElse(a) {
return a - 1;
}
var b;
doSomething( 2 ); // 15
複製代碼
關注這裏的變量b
和doSomethingElse
函數,極可能是doSomething
函數的"私有細節",容許外圍的做用可訪問不只不必並且多是危險的。更加恰當的設計是將全部私有細節隱藏在doSomething
內部:github
function doSomething(a) {
function doSomethingElse(a) {
return a - 1;
}
var b;
b = a + doSomethingElse( a * 2 );
console.log( b * 3 );
}
doSomething( 2 ); // 15
複製代碼
驅使作這樣的代碼隱藏,是一種成爲「最低權限原則」的軟件設計原則,也被稱爲「最低受權」或「最少曝光」,即僅暴露所須要的最低限度的東西。結合上個代碼片斷,結合函數包圍代碼這個主體,是用哪一個做用域來包含變量和函數最適合的選擇。bash
咱們看第二個代碼片斷:函數
var a = 2;
function foo() { // <-- 插入這個
var a = 3;
console.log( a ); // 3
} // <-- 和這個
foo(); // <-- 還有這個
console.log( a ); // 2
複製代碼
在這段代碼中,有函數包圍代碼的痕跡,foo
函數存在的意義只是保障內部變量a
的聲明和a
的輸出。可是額外引入了兩個問題:post
foo
污染了外部做用域foo
——foo()
IIFE——當即調用的函數表達式能夠解決這個問題:ui
var a = 2;
(function foo(){ // <-- 插入這個
var a = 3;
console.log( a ); // 3
})(); // <-- 和這個
console.log( a ); // 2
複製代碼
標識符名稱foo
僅存在於函數foo
內,且函數當即調用。this
YDKJS-SCOPE CLOSURES-ch3 在討論IIFE時候,引入了命名函數和匿名函數的比較,認爲命名函數完勝,三條理由:spa
arguments.callee
調用本身但架不住匿名函數方便阿,好比像arr#map
、arr#filter
等第一個參數傳函數,使用箭頭函數()=>{}
比較便利。因此咱們來試着反駁這三條命名函數完勝的理由:debug
(anonymous)
,一個是帶名字的,可是debugger位置都是定位的,so...問題不是很大總結一下:若是函數須要在以後調用本身,使用命名函數,不然其實匿名函數更加方便;若是使用了命名函數,函數命名要講究,找了找函數命名規範:
動詞 | 含義 | 返回值 |
---|---|---|
can | 判斷是否可執行某個動做 ( 權限 ) | 函數返回一個布爾值。true:可執行;false:不可執行 |
has | 判斷是否含有某個值 | 函數返回一個布爾值。true:含有此值;false:不含有此值 |
is | 判斷是否爲某個值 | 函數返回一個布爾值。true:爲某個值;false:不爲某個值 |
get | 獲取某個值 | 函數返回一個非布爾值 |
set | 設置某個值 | 無返回值、返回是否設置成功或者返回鏈式對象 |
好比:
//是否可閱讀
function canRead(){
return true;
}
//獲取姓名
function getName{
return this.name
}
複製代碼