经过构造器的方式来建立函数,最后一个参数为函数体其余为形参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(); } /*