走进JavaScript——重拾函数

建立函数

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

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();
}
/*
相关文章
相关标签/搜索