我們知道任何一個自定義函數都是Function構造器的實例,所以我們可以通過new Function的方式來創建函數,使用語法很簡單, new Function(形參1, 形參2, ..., 形參N, 函數體) 註意,裡面的參數全部是以字元串的形式呈現。比如一個簡單的例子——要求寫一個函數, 求兩個
我們知道任何一個自定義函數都是Function構造器的實例,所以我們可以通過new Function的方式來創建函數,使用語法很簡單,
new Function(形參1, 形參2, ..., 形參N, 函數體)
註意,裡面的參數全部是以字元串的形式呈現。比如一個簡單的例子——要求寫一個函數, 求兩個數字中最大的數字, 並返回最大數字。如果按照聲明式函數的思想來寫,可能會是這樣
function max(a,b){ return a > b ? a : b; }
但我們轉化到函數構造器(new Function)的方式去寫,會是這樣
var fn = new Function('a','b','return a>b?a:b'); var max = fn(1,2); max; //2
當然,看到這裡,我們並沒有看出以函數構造器的方式創建函數相對於聲明式函數來說具有某方面的優勢。但我們繼續看下一個稍複雜點的例子:
寫一個函數, 傳入任意個參數, 求最大值 。我們以這兩種方法寫出它。
function max() { var a = arguments; var m = a[0]; for (var i = 0; i < a.length; i++) { if (m < a[i]) { m = a[i]; } } return m; } var res = max(1, 5, 16, 3,2); console.log(res); //16
var fn = new Function( 'var a = arguments;'+ 'var m = a[0];'+ 'for (var i = 0; i < a.length; i++) {'+ ' if (m < a[i]) {'+ ' m = a[i];'+ ' }'+ '}'+ 'return m;' ); var res = fn(1,5,16,3,2); console.log(res); //16
然後我們可以將上面的代碼優化一下,將函數體抽出來放在獨立的一個script標簽中。
<script id="control"> /* var max = arguments[0]; for(var i=0;i<arguments.length;i++){ if(arguments[i]>max){ max = arguments[i]; } } return max; */ </script> <script> var fn = new Function( document.getElementById('control').innerHTML .trim() .replace('/*', '') .replace('*/', '') ) var foo = fn(1,2,10,4) console.log(foo) //10 </script>
這樣寫的好處是當需要更改函數方法時,只需要在第一個script標簽裡面改,並不影響下麵script標簽。
再補充一點關於函數構造器的作用域的問題,它跟聲明式函數的不同是,聲明式函數內部可以訪問外部或者說外函數的局部變數,但是函數構造器卻不能。
var globalVal = 'global' function fn(){ var localVal = 'local'; function foo(){ console.log(typeof localVal,typeof globalVal); } foo() } fn() //string string
var globalVal = 'global' function fn(){ var localVal = 'local'; new Function('console.log(typeof localVal,typeof globalVal);')(); } fn() // undefined global