zoukankan      html  css  js  c++  java
  • 走进JavaScript——重拾函数

    创建函数

    通过构造器的方式来创建函数,最后一个参数为函数体其他为形参

    new Function('a','b','alert(a)')
    /* function anonymous(a,b) {
        	alert(a)
       }
    */
    

    由于函数体是通过字符串拼接的,因此我们可以用这个特性来实现代码的组合

    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字符串转对象

    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
    

    我们可以将返回的函数作为构造器来创建对象

    new new Function();
    // Object {}
    

    执行函数

    函数名加()可以执行一个函数

    function foo(){
    	console.log(123);
    }
    foo();
    // 123
    

    那如果没有函数名呢

    function(){};
    // Uncaught SyntaxError: Unexpected token (
    

    也就是不支持直接这么写,我们需要将以上函数改成一段表达式,将函数进行运算就成表达式了

    '' + function(){console.log(5)};
    // "function (){console.log(5)}"
    

    那么怎么执行它呢,在函数后面加()

    '' + function(){console.log(5)}();
    // 5
    

    以上代码不太优雅对吧,我们可以用一个()将它包起来

    (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();
    }
    /*
    
  • 相关阅读:
    Six steps to create google map in the HTML5
    Vocabularies on vegetable, fruit, meat etc.
    常用的Windows命令
    sqlhelper
    素材
    sql sever 跨库查询
    在annotation中却会有ERROR: Duplicate entry
    一份Java学习路线图
    Java算法实例集合(2)
    Java编程规范实践
  • 原文地址:https://www.cnblogs.com/pssp/p/6921700.html
Copyright © 2011-2022 走看看