經過構造器的方式來建立函數,最後一個參數爲函數體其餘爲形參javascript
new Function('a','b','alert(a)') /* function anonymous(a,b) { alert(a) } */
因爲函數體是經過字符串拼接的,所以咱們能夠用這個特性來實現代碼的組合java
function foo(){ var a = 10; console.log(a); } new Function('say',foo + 'foo();console.log(say)')('Hello foo'); // 10 // Hello foo // 實際上以上代碼是這樣的 function anonymous(say) { function foo(){ var a = 10; console.log(a); }foo();console.log(say) }
還能夠用這個特性來實現json字符串轉對象json
var json = '{a:123, b:456}'; new Function('return ' + json)(); // Object {a: 123, b: 456}
甚至咱們能夠利用它來實現重載運算符函數
function calc(num1,num2,operator){ return new Function('return ' + num1 + operator + num2)(); } console.log(calc(2,3,'+')); console.log(calc(5,2,'-')); // 5 // 3
咱們能夠將返回的函數做爲構造器來建立對象code
new new Function(); // Object {}
函數名加()能夠執行一個函數對象
function foo(){ console.log(123); } foo(); // 123
那若是沒有函數名呢token
function(){}; // Uncaught SyntaxError: Unexpected token (
也就是不支持直接這麼寫,咱們須要將以上函數改爲一段表達式,將函數進行運算就成表達式了ip
'' + function(){console.log(5)}; // "function (){console.log(5)}"
那麼怎麼執行它呢,在函數後面加()字符串
'' + function(){console.log(5)}(); // 5
以上代碼不太優雅對吧,咱們能夠用一個()將它包起來io
(function(){console.log(123)}()); // 123
()也是會進行運算的
(1) // 1
只要你給函數傳遞參數它就會進行運算,並不會由於你沒有使用它
var a = 10; (function(){}(a++,a++)); console.log(a); // 12
非惰性求值得另一個例子就是在使用alert時
var a = 1; alert(a+=1,a++); // 2 console.log(a); // 3
第一個輸出2是由於alert只接受一個參數,但因爲函數是不限制參數個數的而且是非惰性求值因此alert中的第二個參數仍是會被運算只是沒有被alert使用罷了
callee的意義就在於當咱們使用匿名函數時能夠去調用函數自己
var a = 0; (function(){ if(a > 3) return; console.log(++a); arguments.callee(); }()); // 1 // 2 // 3 // 4
還有一種狀況是當咱們重寫函數時
var a = 0; function foo(){ if(a > 2)return; console.log(++a); foo = null; arguments.callee(); } foo() // 1 // 2 // 3
caller的意義就在於咱們可以知道此函數是被誰調用的
function f1(){ f2(); } function f2(){ console.log(arguments.callee.caller); } f1(); /* function f1(){ f2(); } /*